mirror of git://gcc.gnu.org/git/gcc.git
OpenMP: 'interop' construct - add ME support + target-independent libgomp
This patch partially enables use of the OpenMP interop construct by adding
middle end support, mostly in the omplower pass, and in the target-independent
part of the libgomp runtime. It follows up on previous patches for C, C++ and
Fortran front ends support. The full interop feature requires another patch to
enable foreign runtime support in libgomp plugins.
gcc/ChangeLog:
* builtin-types.def
(BT_FN_VOID_INT_INT_PTR_PTR_PTR_INT_PTR_INT_PTR_UINT_PTR): New.
* gimple-low.cc (lower_stmt): Handle GIMPLE_OMP_INTEROP.
* gimple-pretty-print.cc (dump_gimple_omp_interop): New function.
(pp_gimple_stmt_1): Handle GIMPLE_OMP_INTEROP.
* gimple.cc (gimple_build_omp_interop): New function.
(gimple_copy): Handle GIMPLE_OMP_INTEROP.
* gimple.def (GIMPLE_OMP_INTEROP): Define.
* gimple.h (gimple_build_omp_interop): Declare.
(gimple_omp_interop_clauses): New function.
(gimple_omp_interop_clauses_ptr): Likewise.
(gimple_omp_interop_set_clauses): Likewise.
(gimple_return_set_retval): Handle GIMPLE_OMP_INTEROP.
* gimplify.cc (gimplify_scan_omp_clauses): Handle OMP_CLAUSE_INIT,
OMP_CLAUSE_USE and OMP_CLAUSE_DESTROY.
(gimplify_omp_interop): New function.
(gimplify_expr): Replace sorry with call to gimplify_omp_interop.
* omp-builtins.def (BUILT_IN_GOMP_INTEROP): Define.
* omp-low.cc (scan_sharing_clauses): Handle OMP_CLAUSE_INIT,
OMP_CLAUSE_USE and OMP_CLAUSE_DESTROY.
(scan_omp_1_stmt): Handle GIMPLE_OMP_INTEROP.
(lower_omp_interop_action_clauses): New function.
(lower_omp_interop): Likewise.
(lower_omp_1): Handle GIMPLE_OMP_INTEROP.
gcc/c/ChangeLog:
* c-parser.cc (c_parser_omp_clause_destroy): Make addressable.
(c_parser_omp_clause_init): Make addressable.
gcc/cp/ChangeLog:
* parser.cc (cp_parser_omp_clause_init): Make addressable.
gcc/fortran/ChangeLog:
* trans-openmp.cc (gfc_trans_omp_clauses): Make OMP_CLAUSE_DESTROY and
OMP_CLAUSE_INIT addressable.
* types.def (BT_FN_VOID_INT_INT_PTR_PTR_PTR_INT_PTR_INT_PTR_UINT_PTR):
New.
include/ChangeLog:
* gomp-constants.h (GOMP_DEVICE_DEFAULT_OMP_61, GOMP_INTEROP_TARGET,
GOMP_INTEROP_TARGETSYNC, GOMP_INTEROP_FLAG_NOWAIT): Define.
libgomp/ChangeLog:
* icv-device.c (omp_set_default_device): Check
GOMP_DEVICE_DEFAULT_OMP_61.
* libgomp-plugin.h (struct interop_obj_t): New.
(enum gomp_interop_flag): New.
(GOMP_OFFLOAD_interop): Declare.
(GOMP_OFFLOAD_get_interop_int): Declare.
(GOMP_OFFLOAD_get_interop_ptr): Declare.
(GOMP_OFFLOAD_get_interop_str): Declare.
(GOMP_OFFLOAD_get_interop_type_desc): Declare.
* libgomp.h (_LIBGOMP_OMP_LOCK_DEFINED): Define.
(struct gomp_device_descr): Add interop_func, get_interop_int_func,
get_interop_ptr_func, get_interop_str_func, get_interop_type_desc_func.
* libgomp.map: Add GOMP_interop.
* libgomp_g.h (GOMP_interop): Declare.
* target.c (resolve_device): Handle GOMP_DEVICE_DEFAULT_OMP_61.
(omp_get_interop_int): Replace stub with actual implementation.
(omp_get_interop_ptr): Likewise.
(omp_get_interop_str): Likewise.
(omp_get_interop_type_desc): Likewise.
(struct interop_data_t): Define.
(gomp_interop_internal): New function.
(GOMP_interop): Likewise.
(gomp_load_plugin_for_device): Load symbols for get_interop_int,
get_interop_ptr, get_interop_str and get_interop_type_desc.
* testsuite/libgomp.c-c++-common/interop-1.c: New test.
gcc/testsuite/ChangeLog:
* c-c++-common/gomp/interop-1.c: Remove dg-prune-output "sorry".
* c-c++-common/gomp/interop-2.c: Likewise.
* c-c++-common/gomp/interop-3.c: Likewise.
* c-c++-common/gomp/interop-4.c: Remove dg-message "not supported".
* g++.dg/gomp/interop-5.C: Likewise.
* gfortran.dg/gomp/interop-4.f90: Likewise.
* c-c++-common/gomp/interop-5.c: New test.
* gfortran.dg/gomp/interop-5.f90: New test.
Co-authored-by: Tobias Burnus <tburnus@baylibre.com>
(cherry picked from commit 99e2906ae2)
This commit is contained in:
parent
5dd8e647be
commit
3560ef45c0
|
|
@ -1,3 +1,34 @@
|
||||||
|
2025-03-21 Paul-Antoine Arras <parras@baylibre.com>
|
||||||
|
|
||||||
|
Backported from master:
|
||||||
|
2025-03-21 Paul-Antoine Arras <parras@baylibre.com>
|
||||||
|
Tobias Burnus <tburnus@baylibre.com>
|
||||||
|
|
||||||
|
* builtin-types.def
|
||||||
|
(BT_FN_VOID_INT_INT_PTR_PTR_PTR_INT_PTR_INT_PTR_UINT_PTR): New.
|
||||||
|
* gimple-low.cc (lower_stmt): Handle GIMPLE_OMP_INTEROP.
|
||||||
|
* gimple-pretty-print.cc (dump_gimple_omp_interop): New function.
|
||||||
|
(pp_gimple_stmt_1): Handle GIMPLE_OMP_INTEROP.
|
||||||
|
* gimple.cc (gimple_build_omp_interop): New function.
|
||||||
|
(gimple_copy): Handle GIMPLE_OMP_INTEROP.
|
||||||
|
* gimple.def (GIMPLE_OMP_INTEROP): Define.
|
||||||
|
* gimple.h (gimple_build_omp_interop): Declare.
|
||||||
|
(gimple_omp_interop_clauses): New function.
|
||||||
|
(gimple_omp_interop_clauses_ptr): Likewise.
|
||||||
|
(gimple_omp_interop_set_clauses): Likewise.
|
||||||
|
(gimple_return_set_retval): Handle GIMPLE_OMP_INTEROP.
|
||||||
|
* gimplify.cc (gimplify_scan_omp_clauses): Handle OMP_CLAUSE_INIT,
|
||||||
|
OMP_CLAUSE_USE and OMP_CLAUSE_DESTROY.
|
||||||
|
(gimplify_omp_interop): New function.
|
||||||
|
(gimplify_expr): Replace sorry with call to gimplify_omp_interop.
|
||||||
|
* omp-builtins.def (BUILT_IN_GOMP_INTEROP): Define.
|
||||||
|
* omp-low.cc (scan_sharing_clauses): Handle OMP_CLAUSE_INIT,
|
||||||
|
OMP_CLAUSE_USE and OMP_CLAUSE_DESTROY.
|
||||||
|
(scan_omp_1_stmt): Handle GIMPLE_OMP_INTEROP.
|
||||||
|
(lower_omp_interop_action_clauses): New function.
|
||||||
|
(lower_omp_interop): Likewise.
|
||||||
|
(lower_omp_1): Handle GIMPLE_OMP_INTEROP.
|
||||||
|
|
||||||
2025-03-19 Thomas Schwinge <tschwinge@baylibre.com>
|
2025-03-19 Thomas Schwinge <tschwinge@baylibre.com>
|
||||||
|
|
||||||
Backported from trunk:
|
Backported from trunk:
|
||||||
|
|
|
||||||
|
|
@ -990,6 +990,9 @@ DEF_FUNCTION_TYPE_11 (BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_UINT_LONG_INT_ULL_
|
||||||
BT_PTR_FN_VOID_PTR_PTR, BT_LONG, BT_LONG,
|
BT_PTR_FN_VOID_PTR_PTR, BT_LONG, BT_LONG,
|
||||||
BT_UINT, BT_LONG, BT_INT,
|
BT_UINT, BT_LONG, BT_INT,
|
||||||
BT_ULONGLONG, BT_ULONGLONG, BT_ULONGLONG)
|
BT_ULONGLONG, BT_ULONGLONG, BT_ULONGLONG)
|
||||||
|
DEF_FUNCTION_TYPE_11 (BT_FN_VOID_INT_INT_PTR_PTR_PTR_INT_PTR_INT_PTR_UINT_PTR,
|
||||||
|
BT_VOID, BT_INT, BT_INT, BT_PTR, BT_PTR, BT_PTR, BT_INT,
|
||||||
|
BT_PTR, BT_INT, BT_PTR, BT_UINT, BT_PTR)
|
||||||
|
|
||||||
DEF_FUNCTION_TYPE_VAR_0 (BT_FN_VOID_VAR, BT_VOID)
|
DEF_FUNCTION_TYPE_VAR_0 (BT_FN_VOID_VAR, BT_VOID)
|
||||||
DEF_FUNCTION_TYPE_VAR_0 (BT_FN_INT_VAR, BT_INT)
|
DEF_FUNCTION_TYPE_VAR_0 (BT_FN_INT_VAR, BT_INT)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,12 @@
|
||||||
|
2025-03-21 Paul-Antoine Arras <parras@baylibre.com>
|
||||||
|
|
||||||
|
Backported from master:
|
||||||
|
2025-03-21 Paul-Antoine Arras <parras@baylibre.com>
|
||||||
|
Tobias Burnus <tburnus@baylibre.com>
|
||||||
|
|
||||||
|
* c-parser.cc (c_parser_omp_clause_destroy): Make addressable.
|
||||||
|
(c_parser_omp_clause_init): Make addressable.
|
||||||
|
|
||||||
2025-03-18 Sandra Loosemore <sloosemore@baylibre.com>
|
2025-03-18 Sandra Loosemore <sloosemore@baylibre.com>
|
||||||
|
|
||||||
Backported from master:
|
Backported from master:
|
||||||
|
|
|
||||||
|
|
@ -20240,7 +20240,10 @@ c_parser_omp_clause_detach (c_parser *parser, tree list)
|
||||||
static tree
|
static tree
|
||||||
c_parser_omp_clause_destroy (c_parser *parser, tree list)
|
c_parser_omp_clause_destroy (c_parser *parser, tree list)
|
||||||
{
|
{
|
||||||
return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_DESTROY, list);
|
tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_DESTROY, list);
|
||||||
|
for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
|
||||||
|
TREE_ADDRESSABLE (OMP_CLAUSE_DECL (c)) = 1;
|
||||||
|
return nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OpenMP 5.1:
|
/* OpenMP 5.1:
|
||||||
|
|
@ -20621,6 +20624,7 @@ c_parser_omp_clause_init (c_parser *parser, tree list)
|
||||||
|
|
||||||
for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
|
for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
|
||||||
{
|
{
|
||||||
|
TREE_ADDRESSABLE (OMP_CLAUSE_DECL (c)) = 1;
|
||||||
if (target)
|
if (target)
|
||||||
OMP_CLAUSE_INIT_TARGET (c) = 1;
|
OMP_CLAUSE_INIT_TARGET (c) = 1;
|
||||||
if (targetsync)
|
if (targetsync)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,11 @@
|
||||||
|
2025-03-21 Paul-Antoine Arras <parras@baylibre.com>
|
||||||
|
|
||||||
|
Backported from master:
|
||||||
|
2025-03-21 Paul-Antoine Arras <parras@baylibre.com>
|
||||||
|
Tobias Burnus <tburnus@baylibre.com>
|
||||||
|
|
||||||
|
* parser.cc (cp_parser_omp_clause_init): Make addressable.
|
||||||
|
|
||||||
2025-01-30 Tobias Burnus <tburnus@baylibre.com>
|
2025-01-30 Tobias Burnus <tburnus@baylibre.com>
|
||||||
|
|
||||||
Backported from master:
|
Backported from master:
|
||||||
|
|
|
||||||
|
|
@ -43501,6 +43501,7 @@ cp_parser_omp_clause_init (cp_parser *parser, tree list)
|
||||||
NULL);
|
NULL);
|
||||||
for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
|
for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
|
||||||
{
|
{
|
||||||
|
TREE_ADDRESSABLE (OMP_CLAUSE_DECL (c)) = 1;
|
||||||
if (target)
|
if (target)
|
||||||
OMP_CLAUSE_INIT_TARGET (c) = 1;
|
OMP_CLAUSE_INIT_TARGET (c) = 1;
|
||||||
if (targetsync)
|
if (targetsync)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,14 @@
|
||||||
|
2025-03-21 Paul-Antoine Arras <parras@baylibre.com>
|
||||||
|
|
||||||
|
Backported from master:
|
||||||
|
2025-03-21 Paul-Antoine Arras <parras@baylibre.com>
|
||||||
|
Tobias Burnus <tburnus@baylibre.com>
|
||||||
|
|
||||||
|
* trans-openmp.cc (gfc_trans_omp_clauses): Make OMP_CLAUSE_DESTROY and
|
||||||
|
OMP_CLAUSE_INIT addressable.
|
||||||
|
* types.def (BT_FN_VOID_INT_INT_PTR_PTR_PTR_INT_PTR_INT_PTR_UINT_PTR):
|
||||||
|
New.
|
||||||
|
|
||||||
2025-03-18 Tobias Burnus <tburnus@baylibre.com>
|
2025-03-18 Tobias Burnus <tburnus@baylibre.com>
|
||||||
|
|
||||||
Backported from master:
|
Backported from master:
|
||||||
|
|
|
||||||
|
|
@ -4803,9 +4803,6 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
|
||||||
case OMP_LIST_USE:
|
case OMP_LIST_USE:
|
||||||
clause_code = OMP_CLAUSE_USE;
|
clause_code = OMP_CLAUSE_USE;
|
||||||
goto add_clause;
|
goto add_clause;
|
||||||
case OMP_LIST_DESTROY:
|
|
||||||
clause_code = OMP_CLAUSE_DESTROY;
|
|
||||||
goto add_clause;
|
|
||||||
case OMP_LIST_INTEROP:
|
case OMP_LIST_INTEROP:
|
||||||
clause_code = OMP_CLAUSE_INTEROP;
|
clause_code = OMP_CLAUSE_INTEROP;
|
||||||
goto add_clause;
|
goto add_clause;
|
||||||
|
|
@ -4816,6 +4813,22 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
|
||||||
declare_simd);
|
declare_simd);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OMP_LIST_DESTROY:
|
||||||
|
for (; n != NULL; n = n->next)
|
||||||
|
if (n->sym->attr.referenced)
|
||||||
|
{
|
||||||
|
tree t = gfc_trans_omp_variable (n->sym, declare_simd);
|
||||||
|
if (t != error_mark_node)
|
||||||
|
{
|
||||||
|
tree node
|
||||||
|
= build_omp_clause (input_location, OMP_CLAUSE_DESTROY);
|
||||||
|
OMP_CLAUSE_DECL (node) = t;
|
||||||
|
TREE_ADDRESSABLE (OMP_CLAUSE_DECL (node)) = 1;
|
||||||
|
omp_clauses = gfc_trans_add_clause (node, omp_clauses);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case OMP_LIST_INIT:
|
case OMP_LIST_INIT:
|
||||||
{
|
{
|
||||||
tree pref_type = NULL_TREE;
|
tree pref_type = NULL_TREE;
|
||||||
|
|
@ -4829,6 +4842,7 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
|
||||||
tree node = build_omp_clause (input_location,
|
tree node = build_omp_clause (input_location,
|
||||||
OMP_CLAUSE_INIT);
|
OMP_CLAUSE_INIT);
|
||||||
OMP_CLAUSE_DECL (node) = t;
|
OMP_CLAUSE_DECL (node) = t;
|
||||||
|
TREE_ADDRESSABLE (OMP_CLAUSE_DECL (node)) = 1;
|
||||||
if (n->u.init.target)
|
if (n->u.init.target)
|
||||||
OMP_CLAUSE_INIT_TARGET (node) = 1;
|
OMP_CLAUSE_INIT_TARGET (node) = 1;
|
||||||
if (n->u.init.targetsync)
|
if (n->u.init.targetsync)
|
||||||
|
|
|
||||||
|
|
@ -272,6 +272,9 @@ DEF_FUNCTION_TYPE_11 (BT_FN_VOID_OMPFN_PTR_OMPCPYFN_LONG_LONG_UINT_LONG_INT_ULL_
|
||||||
BT_PTR_FN_VOID_PTR_PTR, BT_LONG, BT_LONG,
|
BT_PTR_FN_VOID_PTR_PTR, BT_LONG, BT_LONG,
|
||||||
BT_UINT, BT_LONG, BT_INT,
|
BT_UINT, BT_LONG, BT_INT,
|
||||||
BT_ULONGLONG, BT_ULONGLONG, BT_ULONGLONG)
|
BT_ULONGLONG, BT_ULONGLONG, BT_ULONGLONG)
|
||||||
|
DEF_FUNCTION_TYPE_11 (BT_FN_VOID_INT_INT_PTR_PTR_PTR_INT_PTR_INT_PTR_UINT_PTR,
|
||||||
|
BT_VOID, BT_INT, BT_INT, BT_PTR, BT_PTR, BT_PTR, BT_INT,
|
||||||
|
BT_PTR, BT_INT, BT_PTR, BT_UINT, BT_PTR)
|
||||||
|
|
||||||
DEF_FUNCTION_TYPE_VAR_0 (BT_FN_VOID_VAR, BT_VOID)
|
DEF_FUNCTION_TYPE_VAR_0 (BT_FN_VOID_VAR, BT_VOID)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -777,6 +777,7 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data)
|
||||||
case GIMPLE_OMP_FOR:
|
case GIMPLE_OMP_FOR:
|
||||||
case GIMPLE_OMP_SCOPE:
|
case GIMPLE_OMP_SCOPE:
|
||||||
case GIMPLE_OMP_DISPATCH:
|
case GIMPLE_OMP_DISPATCH:
|
||||||
|
case GIMPLE_OMP_INTEROP:
|
||||||
case GIMPLE_OMP_SECTIONS:
|
case GIMPLE_OMP_SECTIONS:
|
||||||
case GIMPLE_OMP_SECTIONS_SWITCH:
|
case GIMPLE_OMP_SECTIONS_SWITCH:
|
||||||
case GIMPLE_OMP_SECTION:
|
case GIMPLE_OMP_SECTION:
|
||||||
|
|
|
||||||
|
|
@ -1752,6 +1752,25 @@ dump_gimple_omp_dispatch (pretty_printer *buffer, const gimple *gs, int spc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Dump a GIMPLE_OMP_INTEROP tuple on the pretty_printer BUFFER. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
dump_gimple_omp_interop (pretty_printer *buffer, const gimple *gs, int spc,
|
||||||
|
dump_flags_t flags)
|
||||||
|
{
|
||||||
|
if (flags & TDF_RAW)
|
||||||
|
{
|
||||||
|
dump_gimple_fmt (buffer, spc, flags, "%G <CLAUSES <", gs);
|
||||||
|
dump_omp_clauses (buffer, gimple_omp_interop_clauses (gs), spc, flags);
|
||||||
|
dump_gimple_fmt (buffer, spc, flags, " >");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pp_string (buffer, "#pragma omp interop");
|
||||||
|
dump_omp_clauses (buffer, gimple_omp_interop_clauses (gs), spc, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Dump a GIMPLE_OMP_TARGET tuple on the pretty_printer BUFFER. */
|
/* Dump a GIMPLE_OMP_TARGET tuple on the pretty_printer BUFFER. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -2907,6 +2926,10 @@ pp_gimple_stmt_1 (pretty_printer *buffer, const gimple *gs, int spc,
|
||||||
dump_gimple_omp_dispatch(buffer, gs, spc, flags);
|
dump_gimple_omp_dispatch(buffer, gs, spc, flags);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GIMPLE_OMP_INTEROP:
|
||||||
|
dump_gimple_omp_interop (buffer, gs, spc, flags);
|
||||||
|
break;
|
||||||
|
|
||||||
case GIMPLE_OMP_MASTER:
|
case GIMPLE_OMP_MASTER:
|
||||||
case GIMPLE_OMP_SECTION:
|
case GIMPLE_OMP_SECTION:
|
||||||
case GIMPLE_OMP_STRUCTURED_BLOCK:
|
case GIMPLE_OMP_STRUCTURED_BLOCK:
|
||||||
|
|
|
||||||
|
|
@ -1251,6 +1251,19 @@ gimple_build_omp_dispatch (gimple_seq body, tree clauses)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Build a GIMPLE_OMP_INTEROP statement.
|
||||||
|
|
||||||
|
CLAUSES are any of the OMP interop construct's clauses. */
|
||||||
|
|
||||||
|
gimple *
|
||||||
|
gimple_build_omp_interop (tree clauses)
|
||||||
|
{
|
||||||
|
gimple *p = gimple_alloc (GIMPLE_OMP_INTEROP, 0);
|
||||||
|
gimple_omp_interop_set_clauses (p, clauses);
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
/* Build a GIMPLE_OMP_TARGET statement.
|
/* Build a GIMPLE_OMP_TARGET statement.
|
||||||
|
|
||||||
BODY is the sequence of statements that will be executed.
|
BODY is the sequence of statements that will be executed.
|
||||||
|
|
@ -2204,6 +2217,11 @@ gimple_copy (gimple *stmt)
|
||||||
gimple_omp_dispatch_set_clauses (copy, t);
|
gimple_omp_dispatch_set_clauses (copy, t);
|
||||||
goto copy_omp_body;
|
goto copy_omp_body;
|
||||||
|
|
||||||
|
case GIMPLE_OMP_INTEROP:
|
||||||
|
t = unshare_expr (gimple_omp_interop_clauses (stmt));
|
||||||
|
gimple_omp_interop_set_clauses (copy, t);
|
||||||
|
break;
|
||||||
|
|
||||||
case GIMPLE_OMP_TARGET:
|
case GIMPLE_OMP_TARGET:
|
||||||
{
|
{
|
||||||
gomp_target *omp_target_stmt = as_a <gomp_target *> (stmt);
|
gomp_target *omp_target_stmt = as_a <gomp_target *> (stmt);
|
||||||
|
|
|
||||||
|
|
@ -355,6 +355,10 @@ DEFGSCODE(GIMPLE_OMP_SCOPE, "gimple_omp_scope", GSS_OMP_SINGLE_LAYOUT)
|
||||||
CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */
|
CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */
|
||||||
DEFGSCODE(GIMPLE_OMP_DISPATCH, "gimple_omp_dispatch", GSS_OMP_SINGLE_LAYOUT)
|
DEFGSCODE(GIMPLE_OMP_DISPATCH, "gimple_omp_dispatch", GSS_OMP_SINGLE_LAYOUT)
|
||||||
|
|
||||||
|
/* GIMPLE_OMP_INTEROP <CLAUSES> represents #pragma omp interop
|
||||||
|
CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */
|
||||||
|
DEFGSCODE(GIMPLE_OMP_INTEROP, "gimple_omp_interop", GSS_OMP_SINGLE_LAYOUT)
|
||||||
|
|
||||||
/* OMP_SECTION <BODY> represents #pragma omp section.
|
/* OMP_SECTION <BODY> represents #pragma omp section.
|
||||||
BODY is the sequence of statements in the section body. */
|
BODY is the sequence of statements in the section body. */
|
||||||
DEFGSCODE(GIMPLE_OMP_SECTION, "gimple_omp_section", GSS_OMP)
|
DEFGSCODE(GIMPLE_OMP_SECTION, "gimple_omp_section", GSS_OMP)
|
||||||
|
|
|
||||||
33
gcc/gimple.h
33
gcc/gimple.h
|
|
@ -745,7 +745,8 @@ struct GTY((tag("GSS_OMP_CONTINUE")))
|
||||||
};
|
};
|
||||||
|
|
||||||
/* GIMPLE_OMP_SINGLE, GIMPLE_OMP_ORDERED, GIMPLE_OMP_TASKGROUP,
|
/* GIMPLE_OMP_SINGLE, GIMPLE_OMP_ORDERED, GIMPLE_OMP_TASKGROUP,
|
||||||
GIMPLE_OMP_SCAN, GIMPLE_OMP_MASKED, GIMPLE_OMP_SCOPE, GIMPLE_OMP_DISPATCH. */
|
GIMPLE_OMP_SCAN, GIMPLE_OMP_MASKED, GIMPLE_OMP_SCOPE, GIMPLE_OMP_DISPATCH,
|
||||||
|
GIMPLE_OMP_INTEROP. */
|
||||||
|
|
||||||
struct GTY((tag("GSS_OMP_SINGLE_LAYOUT")))
|
struct GTY((tag("GSS_OMP_SINGLE_LAYOUT")))
|
||||||
gimple_statement_omp_single_layout : public gimple_statement_omp
|
gimple_statement_omp_single_layout : public gimple_statement_omp
|
||||||
|
|
@ -1655,6 +1656,7 @@ gimple *gimple_build_omp_section (gimple_seq);
|
||||||
gimple *gimple_build_omp_structured_block (gimple_seq);
|
gimple *gimple_build_omp_structured_block (gimple_seq);
|
||||||
gimple *gimple_build_omp_scope (gimple_seq, tree);
|
gimple *gimple_build_omp_scope (gimple_seq, tree);
|
||||||
gimple *gimple_build_omp_dispatch (gimple_seq, tree);
|
gimple *gimple_build_omp_dispatch (gimple_seq, tree);
|
||||||
|
gimple *gimple_build_omp_interop (tree);
|
||||||
gimple *gimple_build_omp_master (gimple_seq);
|
gimple *gimple_build_omp_master (gimple_seq);
|
||||||
gimple *gimple_build_omp_masked (gimple_seq, tree);
|
gimple *gimple_build_omp_masked (gimple_seq, tree);
|
||||||
gimple *gimple_build_omp_taskgroup (gimple_seq, tree);
|
gimple *gimple_build_omp_taskgroup (gimple_seq, tree);
|
||||||
|
|
@ -5532,6 +5534,34 @@ gimple_omp_dispatch_set_clauses (gimple *gs, tree clauses)
|
||||||
static_cast<gimple_statement_omp_single_layout *> (gs)->clauses = clauses;
|
static_cast<gimple_statement_omp_single_layout *> (gs)->clauses = clauses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the clauses associated with OMP_INTEROP statement GS. */
|
||||||
|
|
||||||
|
inline tree
|
||||||
|
gimple_omp_interop_clauses (const gimple *gs)
|
||||||
|
{
|
||||||
|
GIMPLE_CHECK (gs, GIMPLE_OMP_INTEROP);
|
||||||
|
return static_cast<const gimple_statement_omp_single_layout *> (gs)->clauses;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a pointer to the clauses associated with OMP_INTEROP statement GS. */
|
||||||
|
|
||||||
|
inline tree *
|
||||||
|
gimple_omp_interop_clauses_ptr (gimple *gs)
|
||||||
|
{
|
||||||
|
GIMPLE_CHECK (gs, GIMPLE_OMP_INTEROP);
|
||||||
|
return &static_cast<gimple_statement_omp_single_layout *> (gs)->clauses;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set CLAUSES to be the clauses associated with OMP interop statement
|
||||||
|
GS. */
|
||||||
|
|
||||||
|
inline void
|
||||||
|
gimple_omp_interop_set_clauses (gimple *gs, tree clauses)
|
||||||
|
{
|
||||||
|
GIMPLE_CHECK (gs, GIMPLE_OMP_INTEROP);
|
||||||
|
static_cast<gimple_statement_omp_single_layout *> (gs)->clauses = clauses;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return the kind of the OMP_FOR statemement G. */
|
/* Return the kind of the OMP_FOR statemement G. */
|
||||||
|
|
||||||
inline int
|
inline int
|
||||||
|
|
@ -6920,6 +6950,7 @@ gimple_return_set_retval (greturn *gs, tree retval)
|
||||||
case GIMPLE_OMP_TEAMS: \
|
case GIMPLE_OMP_TEAMS: \
|
||||||
case GIMPLE_OMP_SCOPE: \
|
case GIMPLE_OMP_SCOPE: \
|
||||||
case GIMPLE_OMP_DISPATCH: \
|
case GIMPLE_OMP_DISPATCH: \
|
||||||
|
case GIMPLE_OMP_INTEROP: \
|
||||||
case GIMPLE_OMP_SECTION: \
|
case GIMPLE_OMP_SECTION: \
|
||||||
case GIMPLE_OMP_STRUCTURED_BLOCK: \
|
case GIMPLE_OMP_STRUCTURED_BLOCK: \
|
||||||
case GIMPLE_OMP_MASTER: \
|
case GIMPLE_OMP_MASTER: \
|
||||||
|
|
|
||||||
|
|
@ -14317,6 +14317,9 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
|
||||||
case OMP_CLAUSE_IF_PRESENT:
|
case OMP_CLAUSE_IF_PRESENT:
|
||||||
case OMP_CLAUSE_FINALIZE:
|
case OMP_CLAUSE_FINALIZE:
|
||||||
case OMP_CLAUSE_INTEROP:
|
case OMP_CLAUSE_INTEROP:
|
||||||
|
case OMP_CLAUSE_INIT:
|
||||||
|
case OMP_CLAUSE_USE:
|
||||||
|
case OMP_CLAUSE_DESTROY:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OMP_CLAUSE__OMPACC_:
|
case OMP_CLAUSE__OMPACC_:
|
||||||
|
|
@ -19421,6 +19424,22 @@ gimplify_omp_declare_mapper (tree *expr_p)
|
||||||
return GS_ALL_DONE;
|
return GS_ALL_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Gimplify an OMP_INTEROP statement. */
|
||||||
|
|
||||||
|
static enum gimplify_status
|
||||||
|
gimplify_omp_interop (tree *expr_p, gimple_seq *pre_p)
|
||||||
|
{
|
||||||
|
tree expr = *expr_p;
|
||||||
|
|
||||||
|
gimplify_scan_omp_clauses (&OMP_INTEROP_CLAUSES (expr), pre_p, ORT_TASK,
|
||||||
|
OMP_INTEROP);
|
||||||
|
gimple *stmt = gimple_build_omp_interop (OMP_INTEROP_CLAUSES (expr));
|
||||||
|
gimplify_seq_add_stmt (pre_p, stmt);
|
||||||
|
*expr_p = NULL_TREE;
|
||||||
|
return GS_ALL_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Replace a metadirective with the candidate directive variants in
|
/* Replace a metadirective with the candidate directive variants in
|
||||||
CANDIDATES. */
|
CANDIDATES. */
|
||||||
|
|
||||||
|
|
@ -20840,9 +20859,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
|
||||||
}
|
}
|
||||||
|
|
||||||
case OMP_INTEROP:
|
case OMP_INTEROP:
|
||||||
sorry_at (EXPR_LOCATION (*expr_p),
|
ret = gimplify_omp_interop (expr_p, pre_p);
|
||||||
"%<#pragma omp interop%> not yet supported");
|
|
||||||
ret = GS_ERROR;
|
|
||||||
break;
|
break;
|
||||||
case OMP_ATOMIC:
|
case OMP_ATOMIC:
|
||||||
case OMP_ATOMIC_READ:
|
case OMP_ATOMIC_READ:
|
||||||
|
|
|
||||||
|
|
@ -402,6 +402,9 @@ DEF_GOMP_BUILTIN (BUILT_IN_GOMP_DOACROSS_ULL_POST, "GOMP_doacross_ull_post",
|
||||||
BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
|
BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
|
||||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_DOACROSS_ULL_WAIT, "GOMP_doacross_ull_wait",
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_DOACROSS_ULL_WAIT, "GOMP_doacross_ull_wait",
|
||||||
BT_FN_VOID_ULL_VAR, ATTR_NOTHROW_LEAF_LIST)
|
BT_FN_VOID_ULL_VAR, ATTR_NOTHROW_LEAF_LIST)
|
||||||
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_INTEROP, "GOMP_interop",
|
||||||
|
BT_FN_VOID_INT_INT_PTR_PTR_PTR_INT_PTR_INT_PTR_UINT_PTR,
|
||||||
|
ATTR_NOTHROW_LIST)
|
||||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL, "GOMP_parallel",
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL, "GOMP_parallel",
|
||||||
BT_FN_VOID_OMPFN_PTR_UINT_UINT, ATTR_NOTHROW_LIST)
|
BT_FN_VOID_OMPFN_PTR_UINT_UINT, ATTR_NOTHROW_LIST)
|
||||||
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_REDUCTIONS,
|
DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_REDUCTIONS,
|
||||||
|
|
|
||||||
233
gcc/omp-low.cc
233
gcc/omp-low.cc
|
|
@ -2162,6 +2162,11 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
|
||||||
install_var_local (decl, ctx);
|
install_var_local (decl, ctx);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OMP_CLAUSE_INIT:
|
||||||
|
case OMP_CLAUSE_USE:
|
||||||
|
case OMP_CLAUSE_DESTROY:
|
||||||
|
break;
|
||||||
|
|
||||||
case OMP_CLAUSE__CACHE_:
|
case OMP_CLAUSE__CACHE_:
|
||||||
case OMP_CLAUSE_NOHOST:
|
case OMP_CLAUSE_NOHOST:
|
||||||
default:
|
default:
|
||||||
|
|
@ -2365,6 +2370,9 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
|
||||||
case OMP_CLAUSE__CONDTEMP_:
|
case OMP_CLAUSE__CONDTEMP_:
|
||||||
case OMP_CLAUSE_USES_ALLOCATORS:
|
case OMP_CLAUSE_USES_ALLOCATORS:
|
||||||
case OMP_CLAUSE__OMPACC_:
|
case OMP_CLAUSE__OMPACC_:
|
||||||
|
case OMP_CLAUSE_INIT:
|
||||||
|
case OMP_CLAUSE_USE:
|
||||||
|
case OMP_CLAUSE_DESTROY:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OMP_CLAUSE__CACHE_:
|
case OMP_CLAUSE__CACHE_:
|
||||||
|
|
@ -4713,6 +4721,10 @@ scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
|
||||||
scan_omp (gimple_omp_body_ptr (stmt), ctx);
|
scan_omp (gimple_omp_body_ptr (stmt), ctx);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GIMPLE_OMP_INTEROP:
|
||||||
|
ctx = new_omp_context (stmt, ctx);
|
||||||
|
break;
|
||||||
|
|
||||||
case GIMPLE_OMP_SECTIONS:
|
case GIMPLE_OMP_SECTIONS:
|
||||||
scan_omp_sections (as_a <gomp_sections *> (stmt), ctx);
|
scan_omp_sections (as_a <gomp_sections *> (stmt), ctx);
|
||||||
break;
|
break;
|
||||||
|
|
@ -15817,6 +15829,222 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Generate code to implement the action-clauses (destroy, init, use) of an
|
||||||
|
OpenMP interop construct. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
lower_omp_interop_action_clauses (gimple_seq *seq, vec<tree> &objs,
|
||||||
|
vec<tree> *interop_types = NULL,
|
||||||
|
vec<tree> *prefer_types = NULL)
|
||||||
|
{
|
||||||
|
if (objs.length () == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
enum omp_clause_code action = OMP_CLAUSE_CODE (objs[0]);
|
||||||
|
if (action == OMP_CLAUSE_INIT)
|
||||||
|
gcc_checking_assert (objs.length () == interop_types->length ()
|
||||||
|
&& objs.length () == prefer_types->length ());
|
||||||
|
else
|
||||||
|
gcc_assert (prefer_types == NULL && interop_types == NULL);
|
||||||
|
|
||||||
|
tree ret_objs = NULL_TREE, ret_interop_types = NULL_TREE,
|
||||||
|
ret_prefer_types = NULL_TREE;
|
||||||
|
|
||||||
|
/* Build an array of interop objects. */
|
||||||
|
|
||||||
|
tree type_obj_pref = build_array_type_nelts (ptr_type_node, objs.length ());
|
||||||
|
ret_objs = create_tmp_var (type_obj_pref, "interopobjs");
|
||||||
|
|
||||||
|
bool have_pref_type = false;
|
||||||
|
if (action == OMP_CLAUSE_INIT)
|
||||||
|
{
|
||||||
|
for (tree pref_type : prefer_types)
|
||||||
|
if (pref_type != NULL_TREE)
|
||||||
|
{
|
||||||
|
have_pref_type = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tree type_tgtsync
|
||||||
|
= build_array_type_nelts (integer_type_node, objs.length ());
|
||||||
|
ret_interop_types = create_tmp_var (type_tgtsync, "tgt_tgtsync");
|
||||||
|
if (have_pref_type)
|
||||||
|
ret_prefer_types = create_tmp_var (type_obj_pref, "pref_type");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret_prefer_types = null_pointer_node;
|
||||||
|
prefer_types->truncate (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; !objs.is_empty (); i++)
|
||||||
|
{
|
||||||
|
tree offset = build_int_cst (integer_type_node, i);
|
||||||
|
tree init = build4 (ARRAY_REF, ptr_type_node, ret_objs, offset, NULL_TREE,
|
||||||
|
NULL_TREE);
|
||||||
|
tree obj = OMP_CLAUSE_DECL (objs.pop ());
|
||||||
|
if (TREE_CODE (TREE_TYPE (obj)) == REFERENCE_TYPE)
|
||||||
|
obj = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (obj)), obj);
|
||||||
|
if (action != OMP_CLAUSE_USE
|
||||||
|
&& TREE_CODE (TREE_TYPE (obj)) != POINTER_TYPE)
|
||||||
|
/* For modifying actions, we need a pointer. */
|
||||||
|
obj = build_fold_addr_expr (obj);
|
||||||
|
else if (action == OMP_CLAUSE_USE
|
||||||
|
&& TREE_CODE (TREE_TYPE (obj)) == POINTER_TYPE)
|
||||||
|
/* For use action, we need the value. */
|
||||||
|
obj = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (obj)), obj);
|
||||||
|
init = build2 (MODIFY_EXPR, ptr_type_node, init,
|
||||||
|
fold_convert (ptr_type_node, obj));
|
||||||
|
gimplify_and_add (init, seq);
|
||||||
|
|
||||||
|
if (action == OMP_CLAUSE_INIT)
|
||||||
|
{
|
||||||
|
init = build4 (ARRAY_REF, integer_type_node, ret_interop_types,
|
||||||
|
offset, NULL_TREE, NULL_TREE);
|
||||||
|
init = build2 (MODIFY_EXPR, integer_type_node, init,
|
||||||
|
interop_types->pop ());
|
||||||
|
gimplify_and_add (init, seq);
|
||||||
|
|
||||||
|
if (have_pref_type)
|
||||||
|
{
|
||||||
|
tree prefer_type = prefer_types->pop ();
|
||||||
|
tree pref = (prefer_type == NULL_TREE
|
||||||
|
? null_pointer_node
|
||||||
|
: build_fold_addr_expr (prefer_type));
|
||||||
|
init = build4 (ARRAY_REF, ptr_type_node, ret_prefer_types, offset,
|
||||||
|
NULL_TREE, NULL_TREE);
|
||||||
|
init = build2 (MODIFY_EXPR, ptr_type_node, init, pref);
|
||||||
|
gimplify_and_add (init, seq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (action == OMP_CLAUSE_INIT)
|
||||||
|
{
|
||||||
|
if (have_pref_type)
|
||||||
|
ret_prefer_types = build_fold_addr_expr (ret_prefer_types);
|
||||||
|
ret_interop_types = build_fold_addr_expr (ret_interop_types);
|
||||||
|
}
|
||||||
|
ret_objs = build_fold_addr_expr (ret_objs);
|
||||||
|
|
||||||
|
gcc_assert (objs.is_empty ()
|
||||||
|
&& (!interop_types || interop_types->is_empty ())
|
||||||
|
&& (!prefer_types || prefer_types->is_empty ()));
|
||||||
|
|
||||||
|
objs.safe_push (ret_objs);
|
||||||
|
if (action == OMP_CLAUSE_INIT)
|
||||||
|
{
|
||||||
|
interop_types->safe_push (ret_interop_types);
|
||||||
|
prefer_types->safe_push (ret_prefer_types);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lower code for an OpenMP interop directive. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
lower_omp_interop (gimple_stmt_iterator *gsi_p, omp_context *ctx)
|
||||||
|
{
|
||||||
|
push_gimplify_context ();
|
||||||
|
|
||||||
|
tree block = make_node (BLOCK);
|
||||||
|
gbind *bind = gimple_build_bind (NULL, NULL, block);
|
||||||
|
gimple_seq bind_body = NULL;
|
||||||
|
|
||||||
|
/* Emit call to GOMP_interop:
|
||||||
|
void
|
||||||
|
GOMP_interop (int device_num, int n_init, omp_interop_t **init,
|
||||||
|
const void *target_targetsync, const void *prefer_type,
|
||||||
|
int n_use, omp_interop_t *use, int n_destroy,
|
||||||
|
omp_interop_t **destroy, unsigned int flags,
|
||||||
|
void **depend) */
|
||||||
|
|
||||||
|
tree flags = NULL_TREE;
|
||||||
|
tree depend = null_pointer_node;
|
||||||
|
tree device_num = NULL_TREE;
|
||||||
|
|
||||||
|
auto_vec<tree> init_objs, use_objs, destroy_objs, prefer_type,
|
||||||
|
target_targetsync;
|
||||||
|
gimple_seq dep_ilist = NULL, dep_olist = NULL;
|
||||||
|
tree clauses = gimple_omp_interop_clauses (gsi_stmt (*gsi_p));
|
||||||
|
for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
|
||||||
|
{
|
||||||
|
switch (OMP_CLAUSE_CODE (c))
|
||||||
|
{
|
||||||
|
case OMP_CLAUSE_INIT:
|
||||||
|
{
|
||||||
|
init_objs.safe_push (c);
|
||||||
|
int target_targetsync_bits = 0;
|
||||||
|
if (OMP_CLAUSE_INIT_TARGET (c))
|
||||||
|
target_targetsync_bits |= GOMP_INTEROP_TARGET;
|
||||||
|
if (OMP_CLAUSE_INIT_TARGETSYNC (c))
|
||||||
|
target_targetsync_bits |= GOMP_INTEROP_TARGETSYNC;
|
||||||
|
tree t = build_int_cst (integer_type_node, target_targetsync_bits);
|
||||||
|
target_targetsync.safe_push (t);
|
||||||
|
prefer_type.safe_push (OMP_CLAUSE_INIT_PREFER_TYPE (c));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OMP_CLAUSE_USE:
|
||||||
|
use_objs.safe_push (c);
|
||||||
|
break;
|
||||||
|
case OMP_CLAUSE_DESTROY:
|
||||||
|
destroy_objs.safe_push (c);
|
||||||
|
break;
|
||||||
|
case OMP_CLAUSE_NOWAIT:
|
||||||
|
flags = build_int_cst (integer_type_node, GOMP_INTEROP_FLAG_NOWAIT);
|
||||||
|
break;
|
||||||
|
case OMP_CLAUSE_DEPEND:
|
||||||
|
{
|
||||||
|
tree *cp = gimple_omp_interop_clauses_ptr (gsi_stmt (*gsi_p));
|
||||||
|
lower_depend_clauses (cp, &dep_ilist, &dep_olist);
|
||||||
|
depend = OMP_CLAUSE_DECL (*cp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OMP_CLAUSE_DEVICE:
|
||||||
|
device_num = OMP_CLAUSE_DEVICE_ID (c);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
gcc_unreachable ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags == NULL_TREE)
|
||||||
|
flags = build_int_cst (integer_type_node, 0);
|
||||||
|
|
||||||
|
if (device_num == NULL_TREE)
|
||||||
|
device_num = build_int_cst (integer_type_node, GOMP_DEVICE_DEFAULT_OMP_61);
|
||||||
|
|
||||||
|
tree n_init = build_int_cst (integer_type_node, init_objs.length ());
|
||||||
|
tree n_use = build_int_cst (integer_type_node, use_objs.length ());
|
||||||
|
tree n_destroy = build_int_cst (integer_type_node, destroy_objs.length ());
|
||||||
|
|
||||||
|
lower_omp_interop_action_clauses (&bind_body, init_objs, &target_targetsync,
|
||||||
|
&prefer_type);
|
||||||
|
lower_omp_interop_action_clauses (&bind_body, use_objs);
|
||||||
|
lower_omp_interop_action_clauses (&bind_body, destroy_objs);
|
||||||
|
|
||||||
|
gimple_seq_add_seq (&bind_body, dep_ilist);
|
||||||
|
tree fn = builtin_decl_explicit (BUILT_IN_GOMP_INTEROP);
|
||||||
|
tree init_arg = init_objs.length () ? init_objs.pop () : null_pointer_node;
|
||||||
|
tree target_targetsync_arg = target_targetsync.length ()
|
||||||
|
? target_targetsync.pop ()
|
||||||
|
: null_pointer_node;
|
||||||
|
tree prefer_type_arg
|
||||||
|
= prefer_type.length () ? prefer_type.pop () : null_pointer_node;
|
||||||
|
tree use_arg = use_objs.length () ? use_objs.pop () : null_pointer_node;
|
||||||
|
tree destroy_arg
|
||||||
|
= destroy_objs.length () ? destroy_objs.pop () : null_pointer_node;
|
||||||
|
gcall *call
|
||||||
|
= gimple_build_call (fn, 11, device_num, n_init, init_arg,
|
||||||
|
target_targetsync_arg, prefer_type_arg, n_use, use_arg,
|
||||||
|
n_destroy, destroy_arg, flags, depend);
|
||||||
|
gimple_seq_add_stmt (&bind_body, call);
|
||||||
|
gimple_seq_add_seq (&bind_body, dep_olist);
|
||||||
|
|
||||||
|
gsi_replace (gsi_p, bind, true);
|
||||||
|
gimple_bind_set_body (bind, bind_body);
|
||||||
|
pop_gimplify_context (bind);
|
||||||
|
gimple_bind_append_vars (bind, ctx->block_vars);
|
||||||
|
BLOCK_VARS (block) = ctx->block_vars;
|
||||||
|
}
|
||||||
|
|
||||||
/* Expand code for an OpenMP teams directive. */
|
/* Expand code for an OpenMP teams directive. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -16118,6 +16346,11 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
|
||||||
gcc_assert (ctx);
|
gcc_assert (ctx);
|
||||||
lower_omp_dispatch (gsi_p, ctx);
|
lower_omp_dispatch (gsi_p, ctx);
|
||||||
break;
|
break;
|
||||||
|
case GIMPLE_OMP_INTEROP:
|
||||||
|
ctx = maybe_lookup_ctx (stmt);
|
||||||
|
gcc_assert (ctx);
|
||||||
|
lower_omp_interop (gsi_p, ctx);
|
||||||
|
break;
|
||||||
case GIMPLE_OMP_SINGLE:
|
case GIMPLE_OMP_SINGLE:
|
||||||
ctx = maybe_lookup_ctx (stmt);
|
ctx = maybe_lookup_ctx (stmt);
|
||||||
gcc_assert (ctx);
|
gcc_assert (ctx);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,17 @@
|
||||||
|
2025-03-21 Paul-Antoine Arras <parras@baylibre.com>
|
||||||
|
|
||||||
|
Backported from master:
|
||||||
|
2025-03-21 Paul-Antoine Arras <parras@baylibre.com>
|
||||||
|
Tobias Burnus <tburnus@baylibre.com>
|
||||||
|
|
||||||
|
* c-c++-common/gomp/interop-1.c: Remove dg-prune-output "sorry".
|
||||||
|
* c-c++-common/gomp/interop-2.c: Likewise.
|
||||||
|
* c-c++-common/gomp/interop-3.c: Likewise.
|
||||||
|
* c-c++-common/gomp/interop-4.c: Remove dg-message "not supported".
|
||||||
|
* g++.dg/gomp/interop-5.C: Likewise.
|
||||||
|
* gfortran.dg/gomp/interop-4.f90: Likewise.
|
||||||
|
* c-c++-common/gomp/interop-5.c: New test.
|
||||||
|
* gfortran.dg/gomp/interop-5.f90: New test.
|
||||||
2025-03-19 Thomas Schwinge <tschwinge@baylibre.com>
|
2025-03-19 Thomas Schwinge <tschwinge@baylibre.com>
|
||||||
|
|
||||||
Backported from trunk:
|
Backported from trunk:
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@
|
||||||
/* { dg-additional-options "-std=c23" { target c } } */
|
/* { dg-additional-options "-std=c23" { target c } } */
|
||||||
/* C++11 and C23 because of 'constexpr'. */
|
/* C++11 and C23 because of 'constexpr'. */
|
||||||
|
|
||||||
/* { dg-prune-output "sorry, unimplemented: '#pragma omp interop' not yet supported" } */
|
|
||||||
|
|
||||||
/* The following definitions are in omp_lib, which cannot be included
|
/* The following definitions are in omp_lib, which cannot be included
|
||||||
in gcc/testsuite/ */
|
in gcc/testsuite/ */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@
|
||||||
/* { dg-additional-options "-std=c23" { target c } } */
|
/* { dg-additional-options "-std=c23" { target c } } */
|
||||||
/* C++11 and C23 because of 'constexpr'. */
|
/* C++11 and C23 because of 'constexpr'. */
|
||||||
|
|
||||||
/* { dg-prune-output "sorry, unimplemented: '#pragma omp interop' not yet supported" } */
|
|
||||||
|
|
||||||
/* The following definitions are in omp_lib, which cannot be included
|
/* The following definitions are in omp_lib, which cannot be included
|
||||||
in gcc/testsuite/ */
|
in gcc/testsuite/ */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
/* { dg-prune-output "sorry, unimplemented: '#pragma omp interop' not yet supported" } */
|
|
||||||
|
|
||||||
/* The following definitions are in omp_lib, which cannot be included
|
/* The following definitions are in omp_lib, which cannot be included
|
||||||
in gcc/testsuite/ */
|
in gcc/testsuite/ */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,18 +34,18 @@ f()
|
||||||
omp_interop_t obj1, obj2, obj3, obj4, obj5, obj6, obj7;
|
omp_interop_t obj1, obj2, obj3, obj4, obj5, obj6, obj7;
|
||||||
int x[6];
|
int x[6];
|
||||||
|
|
||||||
#pragma omp interop init ( obj1, obj2) use (obj3) destroy(obj4) init(obj5) destroy(obj6) use(obj7) /* { dg-message "'#pragma omp interop' not yet supported" } */
|
#pragma omp interop init ( obj1, obj2) use (obj3) destroy(obj4) init(obj5) destroy(obj6) use(obj7)
|
||||||
/* { dg-final { scan-tree-dump-times "#pragma omp interop use\\(obj7\\) destroy\\(obj6\\) init\\(obj5\\) destroy\\(obj4\\) use\\(obj3\\) init\\(obj2\\) init\\(obj1\\)\[\r\n\]" 1 "original" } } */
|
/* { dg-final { scan-tree-dump-times "#pragma omp interop use\\(obj7\\) destroy\\(obj6\\) init\\(obj5\\) destroy\\(obj4\\) use\\(obj3\\) init\\(obj2\\) init\\(obj1\\)\[\r\n\]" 1 "original" } } */
|
||||||
|
|
||||||
#pragma omp interop nowait init (targetsync : obj1, obj2) use (obj3) destroy(obj4) init(target, targetsync : obj5) destroy(obj6) use(obj7) depend(inout: x) /* { dg-message "'#pragma omp interop' not yet supported" } */
|
#pragma omp interop nowait init (targetsync : obj1, obj2) use (obj3) destroy(obj4) init(target, targetsync : obj5) destroy(obj6) use(obj7) depend(inout: x)
|
||||||
/* { dg-final { scan-tree-dump-times "#pragma omp interop depend\\(inout:x\\) use\\(obj7\\) destroy\\(obj6\\) init\\(target, targetsync: obj5\\) destroy\\(obj4\\) use\\(obj3\\) init\\(targetsync: obj2\\) init\\(targetsync: obj1\\) nowait\[\r\n\]" 1 "original" } } */
|
/* { dg-final { scan-tree-dump-times "#pragma omp interop depend\\(inout:x\\) use\\(obj7\\) destroy\\(obj6\\) init\\(target, targetsync: obj5\\) destroy\\(obj4\\) use\\(obj3\\) init\\(targetsync: obj2\\) init\\(targetsync: obj1\\) nowait\[\r\n\]" 1 "original" } } */
|
||||||
|
|
||||||
#pragma omp interop init ( obj1, obj2) init (target: obj3) init(targetsync : obj4) init(target,targetsync: obj5) /* { dg-message "'#pragma omp interop' not yet supported" } */
|
#pragma omp interop init ( obj1, obj2) init (target: obj3) init(targetsync : obj4) init(target,targetsync: obj5)
|
||||||
/* { dg-final { scan-tree-dump-times "#pragma omp interop init\\(target, targetsync: obj5\\) init\\(targetsync: obj4\\) init\\(target: obj3\\) init\\(obj2\\) init\\(obj1\\)\[\r\n\]" 1 "original" } } */
|
/* { dg-final { scan-tree-dump-times "#pragma omp interop init\\(target, targetsync: obj5\\) init\\(targetsync: obj4\\) init\\(target: obj3\\) init\\(obj2\\) init\\(obj1\\)\[\r\n\]" 1 "original" } } */
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
#pragma omp interop init (target, prefer_type(omp_ifr_cuda, omp_ifr_cuda+1, "hsa", "myPrivateInterop", omp_ifr_cuda-2) : obj1, obj2) init (target: obj3) init(prefer_type(omp_ifr_hip, "sycl", omp_ifr_opencl), targetsync : obj4, obj7) init(target,prefer_type("level_zero", omp_ifr_level_zero+0),targetsync: obj5) /* { dg-message "'#pragma omp interop' not yet supported" } */
|
#pragma omp interop init (target, prefer_type(omp_ifr_cuda, omp_ifr_cuda+1, "hsa", "myPrivateInterop", omp_ifr_cuda-2) : obj1, obj2) init (target: obj3) init(prefer_type(omp_ifr_hip, "sycl", omp_ifr_opencl), targetsync : obj4, obj7) init(target,prefer_type("level_zero", omp_ifr_level_zero+0),targetsync: obj5)
|
||||||
/*
|
/*
|
||||||
{ dg-warning "unknown foreign runtime identifier 'myPrivateInterop' \\\[-Wopenmp\\\]" "" { target *-*-* } .-2 }
|
{ dg-warning "unknown foreign runtime identifier 'myPrivateInterop' \\\[-Wopenmp\\\]" "" { target *-*-* } .-2 }
|
||||||
{ dg-warning "unknown foreign runtime identifier '-1' \\\[-Wopenmp\\\]" "" { target *-*-* } .-3 }
|
{ dg-warning "unknown foreign runtime identifier '-1' \\\[-Wopenmp\\\]" "" { target *-*-* } .-3 }
|
||||||
|
|
@ -56,7 +56,7 @@ f()
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
#pragma omp interop init ( target, prefer_type( {fr("hip"), attr("ompx_gnu_prio:1", "ompx_gnu_debug")}, {attr("ompx_gnu_nicest"), attr("ompx_something")}) : obj1, obj2) init ( prefer_type( {fr("cuda")}, {fr(omp_ifr_cuda_driver), attr("ompx_nix")}, {fr("best")}), targetsync : obj3, obj4) nowait use(obj5) /* { dg-message "'#pragma omp interop' not yet supported" } */
|
#pragma omp interop init ( target, prefer_type( {fr("hip"), attr("ompx_gnu_prio:1", "ompx_gnu_debug")}, {attr("ompx_gnu_nicest"), attr("ompx_something")}) : obj1, obj2) init ( prefer_type( {fr("cuda")}, {fr(omp_ifr_cuda_driver), attr("ompx_nix")}, {fr("best")}), targetsync : obj3, obj4) nowait use(obj5)
|
||||||
/*
|
/*
|
||||||
{ dg-warning "unknown foreign runtime identifier 'best' \\\[-Wopenmp\\\]" "" { target *-*-* } .-2 }
|
{ dg-warning "unknown foreign runtime identifier 'best' \\\[-Wopenmp\\\]" "" { target *-*-* } .-2 }
|
||||||
|
|
||||||
|
|
@ -70,7 +70,7 @@ g (int *y)
|
||||||
{
|
{
|
||||||
omp_interop_t io1, io2, io3, io4, io5;
|
omp_interop_t io1, io2, io3, io4, io5;
|
||||||
|
|
||||||
[[omp::directive (interop,init(prefer_type({fr("level_zero")}, {fr(omp_ifr_sycl),attr("ompx_in_order"),attr("ompx_queue:in_order")}), targetsync : io1, io2),use(io3),destroy(io4,io5),depend(inout:y),nowait)]]; /* { dg-message "'#pragma omp interop' not yet supported" } */
|
[[omp::directive (interop,init(prefer_type({fr("level_zero")}, {fr(omp_ifr_sycl),attr("ompx_in_order"),attr("ompx_queue:in_order")}), targetsync : io1, io2),use(io3),destroy(io4,io5),depend(inout:y),nowait)]];
|
||||||
|
|
||||||
/* { dg-final { scan-tree-dump-times "#pragma omp interop nowait depend\\(inout:y\\) destroy\\(io5\\) destroy\\(io4\\) use\\(io3\\) init\\(prefer_type\\(\{fr\\(\"level_zero\"\\)\}, \{fr\\(\"sycl\"\\),attr\\(\"ompx_in_order\"\\),attr\\(\"ompx_queue:in_order\"\\)\}\\), targetsync: io2\\) init\\(prefer_type\\(\{fr\\(\"level_zero\"\\)\}, \{fr\\(\"sycl\"\\),attr\\(\"ompx_in_order\"\\),attr\\(\"ompx_queue:in_order\"\\)\}\\), targetsync: io1\\)\[\r\n\]" 1 "original" } } */
|
/* { dg-final { scan-tree-dump-times "#pragma omp interop nowait depend\\(inout:y\\) destroy\\(io5\\) destroy\\(io4\\) use\\(io3\\) init\\(prefer_type\\(\{fr\\(\"level_zero\"\\)\}, \{fr\\(\"sycl\"\\),attr\\(\"ompx_in_order\"\\),attr\\(\"ompx_queue:in_order\"\\)\}\\), targetsync: io2\\) init\\(prefer_type\\(\{fr\\(\"level_zero\"\\)\}, \{fr\\(\"sycl\"\\),attr\\(\"ompx_in_order\"\\),attr\\(\"ompx_queue:in_order\"\\)\}\\), targetsync: io1\\)\[\r\n\]" 1 "original" } } */
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
/* { dg-do compile { target { c || c++11 } } } */
|
||||||
|
/* { dg-additional-options "-fdump-tree-omplower" } */
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
typedef enum omp_interop_fr_t
|
||||||
|
{
|
||||||
|
omp_ifr_cuda = 1,
|
||||||
|
omp_ifr_cuda_driver = 2,
|
||||||
|
omp_ifr_opencl = 3,
|
||||||
|
omp_ifr_sycl = 4,
|
||||||
|
omp_ifr_hip = 5,
|
||||||
|
omp_ifr_level_zero = 6,
|
||||||
|
omp_ifr_hsa = 7,
|
||||||
|
omp_ifr_last = omp_ifr_hsa
|
||||||
|
} omp_interop_fr_t;
|
||||||
|
|
||||||
|
void
|
||||||
|
f()
|
||||||
|
{
|
||||||
|
omp_interop_t obj1, obj2, obj3, obj4, obj5, obj6, obj7;
|
||||||
|
int x[6];
|
||||||
|
|
||||||
|
#pragma omp interop init (targetsync: obj1, obj2) use (obj3) destroy(obj4) init(target: obj5) destroy(obj6) use(obj7)
|
||||||
|
/* { dg-final { scan-tree-dump-times "void \\* interopobjs\.\[0-9\]+.3.;\[\r\n\ ]*int tgt_tgtsync\\.\[0-9\]+.3.;\[\r\n\ ]*void \\* interopobjs\\.\[0-9\]+.2.;\[\r\n\ ]*omp_interop_t obj3\\.\[0-9\]+;\[\r\n\ ]*void \\* obj3\\.\[0-9\]+;\[\r\n\ ]*omp_interop_t obj7\\.\[0-9\]+;\[\r\n\ ]*void \\* obj7\\.\[0-9\]+;\[\r\n\ ]*void \\* interopobjs\\.\[0-9\]+.2.;\[\r\n\ ]*interopobjs\.\[0-9\]+.0. = &obj1;\[\r\n \]*tgt_tgtsync\.\[0-9\]+.0. = 2;\[\r\n \]*interopobjs\.\[0-9\]+.1. = &obj2;\[\r\n \]*tgt_tgtsync\.\[0-9\]+.1. = 2;\[\r\n \]*interopobjs\.\[0-9\]+.2. = &obj5;\[\r\n \]*tgt_tgtsync\.\[0-9\]+.2. = 1;\[\r\n \]*obj3\.\[0-9\]+ = obj3;\[\r\n \]*obj3\.\[0-9\]+ = \\(void \\*\\) obj3\.\[0-9\]+;\[\r\n \]*interopobjs\.\[0-9\]+.0. = obj3\.\[0-9\]+;\[\r\n \]*obj7\.\[0-9\]+ = obj7;\[\r\n \]*obj7\.\[0-9\]+ = \\(void \\*\\) obj7\.\[0-9\]+;\[\r\n \]*interopobjs\.\[0-9\]+.1. = obj7\.\[0-9\]+;\[\r\n \]*interopobjs\.\[0-9\]+.0. = &obj4;\[\r\n \]*interopobjs\.\[0-9\]+.1. = &obj6;\[\r\n \]*__builtin_GOMP_interop \\(-5, 3, &interopobjs\.\[0-9\]+, &tgt_tgtsync\.\[0-9\]+, 0B, 2, &interopobjs\.\[0-9\]+, 2, &interopobjs\.\[0-9\]+, 0, 0B\\);" 1 "omplower" { target c } } } */
|
||||||
|
/* { dg-final { scan-tree-dump-times "void \\* interopobjs\.\[0-9\]+.3.;\[\r\n\ ]*int tgt_tgtsync\\.\[0-9\]+.3.;\[\r\n\ ]*void \\* interopobjs\\.\[0-9\]+.2.;\[\r\n\ ]*omp_interop_t obj3\\.\[0-9\]+;\[\r\n\ ]*void \\* obj3\\.\[0-9\]+;\[\r\n\ ]*omp_interop_t obj7\\.\[0-9\]+;\[\r\n\ ]*void \\* obj7\\.\[0-9\]+;\[\r\n\ ]*void \\* interopobjs\\.\[0-9\]+.2.;\[\r\n\ ]*omp_interop_t obj6\\.\[0-9\]+;\[\r\n\ ]*interopobjs\.\[0-9\]+.0. = &obj1;\[\r\n \]*tgt_tgtsync\.\[0-9\]+.0. = 2;\[\r\n \]*interopobjs\.\[0-9\]+.1. = &obj2;\[\r\n \]*tgt_tgtsync\.\[0-9\]+.1. = 2;\[\r\n \]*interopobjs\.\[0-9\]+.2. = &obj5;\[\r\n \]*tgt_tgtsync\.\[0-9\]+.2. = 1;\[\r\n \]*obj3\.\[0-9\]+ = obj3;\[\r\n \]*obj3\.\[0-9\]+ = \\(void \\*\\) obj3\.\[0-9\]+;\[\r\n \]*interopobjs\.\[0-9\]+.0. = obj3\.\[0-9\]+;\[\r\n \]*obj7\.\[0-9\]+ = obj7;\[\r\n \]*obj7\.\[0-9\]+ = \\(void \\*\\) obj7\.\[0-9\]+;\[\r\n \]*interopobjs\.\[0-9\]+.1. = obj7\.\[0-9\]+;\[\r\n \]*interopobjs\.\[0-9\]+.0. = &obj4;\[\r\n \]*obj6\.\[0-9\]+ = obj6;\[\r\n \]*interopobjs\.\[0-9\]+.1. = &obj6\.\[0-9\]+;\[\r\n \]*__builtin_GOMP_interop \\(-5, 3, &interopobjs\.\[0-9\]+, &tgt_tgtsync\.\[0-9\]+, 0B, 2, &interopobjs\.\[0-9\]+, 2, &interopobjs\.\[0-9\]+, 0, 0B\\);" 1 "omplower" { target c++ } } } */
|
||||||
|
|
||||||
|
#pragma omp interop nowait init (targetsync : obj1, obj2) use (obj3) destroy(obj4) init(target, targetsync : obj5) destroy(obj6) use(obj7) depend(inout: x)
|
||||||
|
/* { dg-final { scan-tree-dump-times "void \\* D\\.\[0-9\]+.3.;\[\r\n\ ]*void \\* interopobjs\\.\[0-9\]+.3.;\[\r\n\ ]*int tgt_tgtsync\\.\[0-9\]+.3.;\[\r\n\ ]*void \\* interopobjs\\.\[0-9\]+.2.;\[\r\n\ ]*omp_interop_t obj3\\.\[0-9\]+;\[\r\n\ ]*void \\* obj3\\.\[0-9\]+;\[\r\n\ ]*omp_interop_t obj7\\.\[0-9\]+;\[\r\n\ ]*void \\* obj7\\.\[0-9\]+;\[\r\n\ ]*void \\* interopobjs\\.\[0-9\]+.2.;\[\r\n\ ]*interopobjs\.\[0-9\]+.0. = &obj1;\[\r\n\ ]*tgt_tgtsync\.\[0-9\]+.0. = 2;\[\r\n\ ]*interopobjs\.\[0-9\]+.1. = &obj2;\[\r\n\ ]*tgt_tgtsync\.\[0-9\]+.1. = 2;\[\r\n\ ]*interopobjs\.\[0-9\]+.2. = &obj5;\[\r\n\ ]*tgt_tgtsync\.\[0-9\]+.2. = 3;\[\r\n\ ]*obj3\.\[0-9\]+ = obj3;\[\r\n\ ]*obj3\.\[0-9\]+ = \\(void \\*\\) obj3\.\[0-9\]+;\[\r\n\ ]*interopobjs\.\[0-9\]+.0. = obj3\.\[0-9\]+;\[\r\n\ ]*obj7\.\[0-9\]+ = obj7;\[\r\n\ ]*obj7\.\[0-9\]+ = \\(void \\*\\) obj7\.\[0-9\]+;\[\r\n\ ]*interopobjs\.\[0-9\]+.1. = obj7\.\[0-9\]+;\[\r\n\ ]*interopobjs\.\[0-9\]+.0. = &obj4;\[\r\n\ ]*interopobjs\.\[0-9\]+.1. = &obj6;\[\r\n\ ]*D\.\[0-9\]+.0. = 1B;\[\r\n\ ]*D\.\[0-9\]+.1. = 1B;\[\r\n\ ]*D\.\[0-9\]+.2. = &x;\[\r\n\ ]*__builtin_GOMP_interop \\(-5, 3, &interopobjs\.\[0-9\]+, &tgt_tgtsync\.\[0-9\]+, 0B, 2, &interopobjs\.\[0-9\]+, 2, &interopobjs\.\[0-9\]+, 1, &D\.\[0-9\]+\\);" 1 "omplower" { target c } } } */
|
||||||
|
/* { dg-final { scan-tree-dump-times "void \\* D\\.\[0-9\]+.3.;\[\r\n\ ]*void \\* interopobjs\\.\[0-9\]+.3.;\[\r\n\ ]*int tgt_tgtsync\\.\[0-9\]+.3.;\[\r\n\ ]*void \\* interopobjs\\.\[0-9\]+.2.;\[\r\n\ ]*omp_interop_t obj3\\.\[0-9\]+;\[\r\n\ ]*void \\* obj3\\.\[0-9\]+;\[\r\n\ ]*omp_interop_t obj7\\.\[0-9\]+;\[\r\n\ ]*void \\* obj7\\.\[0-9\]+;\[\r\n\ ]*void \\* interopobjs\\.\[0-9\]+.2.;\[\r\n\ ]*omp_interop_t obj6\\.\[0-9\]+;\[\r\n\ ]*interopobjs\.\[0-9\]+.0. = &obj1;\[\r\n\ ]*tgt_tgtsync\.\[0-9\]+.0. = 2;\[\r\n\ ]*interopobjs\.\[0-9\]+.1. = &obj2;\[\r\n\ ]*tgt_tgtsync\.\[0-9\]+.1. = 2;\[\r\n\ ]*interopobjs\.\[0-9\]+.2. = &obj5;\[\r\n\ ]*tgt_tgtsync\.\[0-9\]+.2. = 3;\[\r\n\ ]*obj3\.\[0-9\]+ = obj3;\[\r\n\ ]*obj3\.\[0-9\]+ = \\(void \\*\\) obj3\.\[0-9\]+;\[\r\n\ ]*interopobjs\.\[0-9\]+.0. = obj3\.\[0-9\]+;\[\r\n\ ]*obj7\.\[0-9\]+ = obj7;\[\r\n\ ]*obj7\.\[0-9\]+ = \\(void \\*\\) obj7\.\[0-9\]+;\[\r\n\ ]*interopobjs\.\[0-9\]+.1. = obj7\.\[0-9\]+;\[\r\n\ ]*interopobjs\.\[0-9\]+.0. = &obj4;\[\r\n\ ]*obj6\.\[0-9\]+ = obj6;\[\r\n\ ]*interopobjs\.\[0-9\]+.1. = &obj6\.\[0-9\]+;\[\r\n\ ]*D\.\[0-9\]+.0. = 1B;\[\r\n\ ]*D\.\[0-9\]+.1. = 1B;\[\r\n\ ]*D\.\[0-9\]+.2. = &x;\[\r\n\ ]*__builtin_GOMP_interop \\(-5, 3, &interopobjs\.\[0-9\]+, &tgt_tgtsync\.\[0-9\]+, 0B, 2, &interopobjs\.\[0-9\]+, 2, &interopobjs\.\[0-9\]+, 1, &D\.\[0-9\]+\\);" 1 "omplower" { target c++ } } } */
|
||||||
|
|
||||||
|
#pragma omp interop init (target: obj1, obj2) init (target: obj3) init(targetsync : obj4) init(target,targetsync: obj5)
|
||||||
|
/* { dg-final { scan-tree-dump-times "void \\* interopobjs\\.\[0-9\]+.5.;\[\r\n\ ]*int tgt_tgtsync\\.\[0-9\]+.5.;\[\r\n\ ]*interopobjs\.\[0-9\]+.0. = &obj1;\[\r\n \]*tgt_tgtsync\.\[0-9\]+.0. = 1;\[\r\n \]*interopobjs\.\[0-9\]+.1. = &obj2;\[\r\n \]*tgt_tgtsync\.\[0-9\]+.1. = 1;\[\r\n \]*interopobjs\.\[0-9\]+.2. = &obj3;\[\r\n \]*tgt_tgtsync\.\[0-9\]+.2. = 1;\[\r\n \]*interopobjs\.\[0-9\]+.3. = &obj4;\[\r\n \]*tgt_tgtsync\.\[0-9\]+.3. = 2;\[\r\n \]*interopobjs\.\[0-9\]+.4. = &obj5;\[\r\n \]*tgt_tgtsync\.\[0-9\]+.4. = 3;\[\r\n\ ]*__builtin_GOMP_interop \\(-5, 5, &interopobjs\.\[0-9\]+, &tgt_tgtsync\.\[0-9\]+, 0B, 0, 0B, 0, 0B, 0, 0B\\);" 1 "omplower" } } */
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
|
#pragma omp interop init (target, prefer_type(omp_ifr_cuda, omp_ifr_cuda+1, "hsa") : obj1, obj2) init (target: obj3) init(prefer_type(omp_ifr_hip, "sycl", omp_ifr_opencl), targetsync : obj4, obj7) init(target,prefer_type("level_zero", omp_ifr_level_zero+0),targetsync: obj5)
|
||||||
|
/* { dg-final { scan-tree-dump-times "void \\* interopobjs\\.\[0-9\]+.6.;\[\r\n\ ]*int tgt_tgtsync\\.\[0-9\]+.6.;\[\r\n\ ]*void \\* pref_type\.\[0-9\]+.6.;\[\r\n\ ]*interopobjs\.\[0-9\]+.0. = &obj1;\[\r\n \]*tgt_tgtsync\.\[0-9\]+.0. = 1;\[\r\n \]*pref_type\.\[0-9\]+.0. = .*;\[\r\n \]*interopobjs\.\[0-9\]+.1. = &obj2;\[\r\n \]*tgt_tgtsync\.\[0-9\]+.1. = 1;\[\r\n \]*pref_type\.\[0-9\]+.1. = .*;\[\r\n \]*interopobjs\.\[0-9\]+.2. = &obj3;\[\r\n \]*tgt_tgtsync\.\[0-9\]+.2. = 1;\[\r\n \]*pref_type\.\[0-9\]+.2. = 0B;\[\r\n \]*interopobjs\.\[0-9\]+.3. = &obj4;\[\r\n \]*tgt_tgtsync\.\[0-9\]+.3. = 2;\[\r\n \]*pref_type\.\[0-9\]+.3. = .*;\[\r\n \]*interopobjs\.\[0-9\]+.4. = &obj7;\[\r\n \]*tgt_tgtsync\.\[0-9\]+.4. = 2;\[\r\n \]*pref_type\.\[0-9\]+.4. = .*;\[\r\n \]*interopobjs\.\[0-9\]+.5. = &obj5;\[\r\n \]*tgt_tgtsync\.\[0-9\]+.5. = 3;\[\r\n \]*pref_type\.\[0-9\]+.5. = .*;\[\r\n\ ]*__builtin_GOMP_interop \\(-5, 6, &interopobjs\.\[0-9\]+, &tgt_tgtsync\.\[0-9\]+, &pref_type\.\[0-9\]+, 0, 0B, 0, 0B, 0, 0B\\);" 1 "omplower" } } */
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
|
#pragma omp interop init ( target, prefer_type( {fr("hip"), attr("ompx_gnu_prio:1", "ompx_gnu_debug")}, {attr("ompx_gnu_nicest"), attr("ompx_something")}) : obj1) destroy(obj3) nowait use(obj5)
|
||||||
|
/* { dg-final { scan-tree-dump-times "void \\* interopobjs\\.\[0-9\]+.1.;\[\r\n\ ]*int tgt_tgtsync\\.\[0-9\]+.1.;\[\r\n\ ]*void \\* pref_type\.\[0-9\]+.1.;\[\r\n\ ]*void \\* interopobjs\.\[0-9\]+.1.;\[\r\n\ ]*omp_interop_t obj5\.\[0-9\]+;\[\r\n\ ]*void \\* obj5\.\[0-9\]+;\[\r\n\ ]*void \\* interopobjs\.\[0-9\]+.1.;\[\r\n\ ]*interopobjs\.\[0-9\]+.0. = &obj1;\[\r\n\ ]*tgt_tgtsync\.\[0-9\]+.0. = 1;\[\r\n\ ]*pref_type\.\[0-9\]+.0. = .*;\[\r\n\ ]*obj5\.\[0-9\]+ = obj5;\[\r\n\ ]*obj5\.\[0-9\]+ = \\(void \\*\\) obj5\.\[0-9\]+;\[\r\n\ ]*interopobjs\.\[0-9\]+.0. = obj5\.\[0-9\]+;\[\r\n\ ]*interopobjs\.\[0-9\]+.0. = &obj3;\[\r\n\ ]*__builtin_GOMP_interop \\(-5, 1, &interopobjs\.\[0-9\]+, &tgt_tgtsync\.\[0-9\]+, &pref_type\.\[0-9\]+, 1, &interopobjs\.\[0-9\]+, 1, &interopobjs\.\[0-9\]+, 1, 0B\\);" 1 "omplower" } } */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g (int *y)
|
||||||
|
{
|
||||||
|
omp_interop_t io1, io2, io3, io4, io5;
|
||||||
|
|
||||||
|
[[omp::directive (interop,init(prefer_type({fr("level_zero")}, {fr(omp_ifr_sycl),attr("ompx_in_order"),attr("ompx_queue:in_order")}), targetsync : io1, io2),use(io3),destroy(io4,io5),depend(inout:y),nowait)]];
|
||||||
|
/* { dg-final { scan-tree-dump-times "void \\* D\.\[0-9\]+.3.;\[\r\n\ ]*void \\* interopobjs\.\[0-9\]+.2.;\[\r\n\ ]*int tgt_tgtsync\.\[0-9\]+.2.;\[\r\n\ ]*void \\* pref_type\.\[0-9\]+.2.;\[\r\n\ ]*void \\* interopobjs\.\[0-9\]+.1.;\[\r\n\ ]*void \\* io3\.\[0-9\]+;\[\r\n\ ]*void \\* interopobjs\.\[0-9\]+.2.;\[\r\n\ ]*interopobjs\.\[0-9\]+.0. = &io1;\[\r\n\ ]*tgt_tgtsync\.\[0-9\]+.0. = 2;\[\r\n\ ]*pref_type\.\[0-9\]+.0. = .*;\[\r\n\ ]*interopobjs\.\[0-9\]+.1. = &io2;\[\r\n\ ]*tgt_tgtsync\.\[0-9\]+.1. = 2;\[\r\n\ ]*pref_type\.\[0-9\]+.1. = .*;\[\r\n\ ]*io3\.\[0-9\]+ = \\(void \\*\\) io3;\[\r\n\ ]*interopobjs\.\[0-9\]+.0. = io3\.\[0-9\]+;\[\r\n\ ]*interopobjs\.\[0-9\]+.0. = &io4;\[\r\n\ ]*interopobjs\.\[0-9\]+.1. = &io5;\[\r\n\ ]*D\.\[0-9\]+.0. = 1B;\[\r\n\ ]*D\.\[0-9\]+.1. = 1B;\[\r\n\ ]*D\.\[0-9\]+.2. = &y;\[\r\n\ ]*__builtin_GOMP_interop \\(-5, 2, &interopobjs\.\[0-9\]+, &tgt_tgtsync\.\[0-9\]+, &pref_type\.\[0-9\]+, 1, &interopobjs\.\[0-9\]+, 2, &interopobjs\.\[0-9\]+, 1, &D\.\[0-9\]+\\);" 1 "omplower" { target c } } } */
|
||||||
|
/* { dg-final { scan-tree-dump-times "void \\* D\.\[0-9\]+.3.;\[\r\n\ ]*void \\* interopobjs\.\[0-9\]+.2.;\[\r\n\ ]*int tgt_tgtsync\.\[0-9\]+.2.;\[\r\n\ ]*void \\* pref_type\.\[0-9\]+.2.;\[\r\n\ ]*void \\* interopobjs\.\[0-9\]+.1.;\[\r\n\ ]*void \\* io3\.\[0-9\]+;\[\r\n\ ]*void \\* interopobjs\.\[0-9\]+.2.;\[\r\n\ ]*omp_interop_t io4\.\[0-9\]+;\[\r\n\ ]*omp_interop_t io5\.\[0-9\]+;\[\r\n\ ]*interopobjs\.\[0-9\]+.0. = &io1;\[\r\n\ ]*tgt_tgtsync\.\[0-9\]+.0. = 2;\[\r\n\ ]*pref_type\.\[0-9\]+.0. = .*;\[\r\n\ ]*interopobjs\.\[0-9\]+.1. = &io2;\[\r\n\ ]*tgt_tgtsync\.\[0-9\]+.1. = 2;\[\r\n\ ]*pref_type\.\[0-9\]+.1. = .*;\[\r\n\ ]*io3\.\[0-9\]+ = \\(void \\*\\) io3;\[\r\n\ ]*interopobjs\.\[0-9\]+.0. = io3\.\[0-9\]+;\[\r\n\ ]*io4\.\[0-9\]+ = io4;\[\r\n\ ]*interopobjs\.\[0-9\]+.0. = &io4\.\[0-9\]+;\[\r\n\ ]*io5\.\[0-9\]+ = io5;\[\r\n\ ]*interopobjs\.\[0-9\]+.1. = &io5\.\[0-9\]+;\[\r\n\ ]*D\.\[0-9\]+.0. = 1B;\[\r\n\ ]*D\.\[0-9\]+.1. = 1B;\[\r\n\ ]*D\.\[0-9\]+.2. = &y;\[\r\n\ ]*__builtin_GOMP_interop \\(-5, 2, &interopobjs\.\[0-9\]+, &tgt_tgtsync\.\[0-9\]+, &pref_type\.\[0-9\]+, 1, &interopobjs\.\[0-9\]+, 2, &interopobjs\.\[0-9\]+, 1, &D\.\[0-9\]+\\);" 1 "omplower" { target c++ } } } */
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
/* { dg-do compile { target c++11 } } */
|
/* { dg-do compile { target c++11 } } */
|
||||||
/* { dg-additional-options "-fdump-tree-original" } */
|
/* { dg-additional-options "-fdump-tree-original" } */
|
||||||
|
|
||||||
/* { dg-prune-output "sorry, unimplemented: '#pragma omp interop' not yet supported" } */
|
|
||||||
|
|
||||||
/* The following definitions are in omp_lib, which cannot be included
|
/* The following definitions are in omp_lib, which cannot be included
|
||||||
in gcc/testsuite/ */
|
in gcc/testsuite/ */
|
||||||
|
|
||||||
|
|
@ -43,13 +41,13 @@ f ()
|
||||||
constexpr T3 ifr_level_zero = (T3) (omp_ifr_sycl + 2);
|
constexpr T3 ifr_level_zero = (T3) (omp_ifr_sycl + 2);
|
||||||
constexpr T3 ifr_invalid = (T3) 99;
|
constexpr T3 ifr_invalid = (T3) 99;
|
||||||
|
|
||||||
#pragma omp interop init ( obj1, obj2) use (obj3) destroy(obj4) init(obj5) destroy(obj6) use(obj7) /* { dg-message "'#pragma omp interop' not yet supported" } */
|
#pragma omp interop init ( obj1, obj2) use (obj3) destroy(obj4) init(obj5) destroy(obj6) use(obj7)
|
||||||
/* { dg-final { scan-tree-dump-times "#pragma omp interop use\\(obj7\\) destroy\\(obj6\\) init\\(obj5\\) destroy\\(obj4\\) use\\(obj3\\) init\\(obj2\\) init\\(obj1\\)\[\r\n\]" 2 "original" } } */
|
/* { dg-final { scan-tree-dump-times "#pragma omp interop use\\(obj7\\) destroy\\(obj6\\) init\\(obj5\\) destroy\\(obj4\\) use\\(obj3\\) init\\(obj2\\) init\\(obj1\\)\[\r\n\]" 2 "original" } } */
|
||||||
|
|
||||||
#pragma omp interop nowait init (targetsync : obj1, obj2) use (obj3) destroy(obj4) init(target, targetsync : obj5) destroy(obj6) use(obj7) depend(inout: x) /* { dg-message "'#pragma omp interop' not yet supported" } */
|
#pragma omp interop nowait init (targetsync : obj1, obj2) use (obj3) destroy(obj4) init(target, targetsync : obj5) destroy(obj6) use(obj7) depend(inout: x)
|
||||||
/* { dg-final { scan-tree-dump-times "#pragma omp interop depend\\(inout:x\\) use\\(obj7\\) destroy\\(obj6\\) init\\(target, targetsync: obj5\\) destroy\\(obj4\\) use\\(obj3\\) init\\(targetsync: obj2\\) init\\(targetsync: obj1\\) nowait\[\r\n\]" 2 "original" } } */
|
/* { dg-final { scan-tree-dump-times "#pragma omp interop depend\\(inout:x\\) use\\(obj7\\) destroy\\(obj6\\) init\\(target, targetsync: obj5\\) destroy\\(obj4\\) use\\(obj3\\) init\\(targetsync: obj2\\) init\\(targetsync: obj1\\) nowait\[\r\n\]" 2 "original" } } */
|
||||||
|
|
||||||
#pragma omp interop init ( obj1, obj2) init (target: obj3) init(targetsync : obj4) init(target,targetsync: obj5) /* { dg-message "'#pragma omp interop' not yet supported" } */
|
#pragma omp interop init ( obj1, obj2) init (target: obj3) init(targetsync : obj4) init(target,targetsync: obj5)
|
||||||
/* { dg-final { scan-tree-dump-times "#pragma omp interop init\\(target, targetsync: obj5\\) init\\(targetsync: obj4\\) init\\(target: obj3\\) init\\(obj2\\) init\\(obj1\\)\[\r\n\]" 2 "original" } } */
|
/* { dg-final { scan-tree-dump-times "#pragma omp interop init\\(target, targetsync: obj5\\) init\\(targetsync: obj4\\) init\\(target: obj3\\) init\\(obj2\\) init\\(obj1\\)\[\r\n\]" 2 "original" } } */
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
@ -64,7 +62,7 @@ f ()
|
||||||
{ dg-final { scan-tree-dump-times "#pragma omp interop init\\(prefer_type\\(\{fr\\(\"<unknown>\"\\)\}, \{fr\\(\"<unknown>\"\\)\}, \{fr\\(\"cuda\"\\)\}, \{fr\\(\"cuda_driver\"\\)\}, \{fr\\(\"hsa\"\\)\}, \{fr\\(\"<unknown>\"\\)\}, \{fr\\(\"<unknown>\"\\)\}\\), target: obj2\\) init\\(prefer_type\\(\{fr\\(\"<unknown>\"\\)\}, \{fr\\(\"<unknown>\"\\)\}, \{fr\\(\"cuda\"\\)\}, \{fr\\(\"cuda_driver\"\\)\}, \{fr\\(\"hsa\"\\)\}, \{fr\\(\"<unknown>\"\\)\}, \{fr\\(\"<unknown>\"\\)\}\\), target: obj1\\)\[\r\n\]" 2 "original" } }
|
{ dg-final { scan-tree-dump-times "#pragma omp interop init\\(prefer_type\\(\{fr\\(\"<unknown>\"\\)\}, \{fr\\(\"<unknown>\"\\)\}, \{fr\\(\"cuda\"\\)\}, \{fr\\(\"cuda_driver\"\\)\}, \{fr\\(\"hsa\"\\)\}, \{fr\\(\"<unknown>\"\\)\}, \{fr\\(\"<unknown>\"\\)\}\\), target: obj2\\) init\\(prefer_type\\(\{fr\\(\"<unknown>\"\\)\}, \{fr\\(\"<unknown>\"\\)\}, \{fr\\(\"cuda\"\\)\}, \{fr\\(\"cuda_driver\"\\)\}, \{fr\\(\"hsa\"\\)\}, \{fr\\(\"<unknown>\"\\)\}, \{fr\\(\"<unknown>\"\\)\}\\), target: obj1\\)\[\r\n\]" 2 "original" } }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma omp interop init (target, prefer_type(ifr_cuda, ifr_cuda+1, "hsa", "myPrivateInterop", ifr_cuda-2) : obj1, obj2) init (target: obj3) init(prefer_type(ifr_hip, "sycl", ifr_opencl), targetsync : obj4, obj7) init(target,prefer_type("level_zero", ifr_level_zero+0),targetsync: obj5) /* { dg-message "'#pragma omp interop' not yet supported" } */
|
#pragma omp interop init (target, prefer_type(ifr_cuda, ifr_cuda+1, "hsa", "myPrivateInterop", ifr_cuda-2) : obj1, obj2) init (target: obj3) init(prefer_type(ifr_hip, "sycl", ifr_opencl), targetsync : obj4, obj7) init(target,prefer_type("level_zero", ifr_level_zero+0),targetsync: obj5)
|
||||||
/*
|
/*
|
||||||
{ dg-warning "unknown foreign runtime identifier 'myPrivateInterop' \\\[-Wopenmp\\\]" "" { target *-*-* } .-2 }
|
{ dg-warning "unknown foreign runtime identifier 'myPrivateInterop' \\\[-Wopenmp\\\]" "" { target *-*-* } .-2 }
|
||||||
{ dg-warning "unknown foreign runtime identifier '-1' \\\[-Wopenmp\\\]" "" { target *-*-* } .-3 }
|
{ dg-warning "unknown foreign runtime identifier '-1' \\\[-Wopenmp\\\]" "" { target *-*-* } .-3 }
|
||||||
|
|
@ -74,7 +72,7 @@ f ()
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
#pragma omp interop init ( target, prefer_type( {fr("hip"), attr("ompx_gnu_prio:1", "ompx_gnu_debug")}, {attr("ompx_gnu_nicest"), attr("ompx_something")}) : obj1, obj2) init ( prefer_type( {fr("cuda")}, {fr(ifr_cuda_driver), attr("ompx_nix")}, {fr("best")}), targetsync : obj3, obj4) nowait use(obj5) /* { dg-message "'#pragma omp interop' not yet supported" } */
|
#pragma omp interop init ( target, prefer_type( {fr("hip"), attr("ompx_gnu_prio:1", "ompx_gnu_debug")}, {attr("ompx_gnu_nicest"), attr("ompx_something")}) : obj1, obj2) init ( prefer_type( {fr("cuda")}, {fr(ifr_cuda_driver), attr("ompx_nix")}, {fr("best")}), targetsync : obj3, obj4) nowait use(obj5)
|
||||||
/*
|
/*
|
||||||
{ dg-warning "unknown foreign runtime identifier 'best' \\\[-Wopenmp\\\]" "" { target *-*-* } .-2 }
|
{ dg-warning "unknown foreign runtime identifier 'best' \\\[-Wopenmp\\\]" "" { target *-*-* } .-2 }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,18 +26,18 @@ implicit none
|
||||||
integer(omp_interop_kind) :: obj1, obj2, obj3, obj4, obj5, obj6, obj7
|
integer(omp_interop_kind) :: obj1, obj2, obj3, obj4, obj5, obj6, obj7
|
||||||
integer :: x(6)
|
integer :: x(6)
|
||||||
|
|
||||||
!$omp interop init ( obj1, obj2) use (obj3) destroy(obj4) init(obj5) destroy(obj6) use(obj7) ! { dg-message "'#pragma omp interop' not yet supported" }
|
!$omp interop init ( obj1, obj2) use (obj3) destroy(obj4) init(obj5) destroy(obj6) use(obj7)
|
||||||
! { dg-final { scan-tree-dump-times "#pragma omp interop init\\(obj1\\) init\\(obj2\\) init\\(obj5\\) use\\(obj3\\) use\\(obj7\\) destroy\\(obj4\\) destroy\\(obj6\\)\[\r\n\]" 1 "original" } }
|
! { dg-final { scan-tree-dump-times "#pragma omp interop init\\(obj1\\) init\\(obj2\\) init\\(obj5\\) use\\(obj3\\) use\\(obj7\\) destroy\\(obj4\\) destroy\\(obj6\\)\[\r\n\]" 1 "original" } }
|
||||||
|
|
||||||
!$omp interop nowait init (targetsync : obj1, obj2) use (obj3) destroy(obj4) init(target, targetsync : obj5) destroy(obj6) use(obj7) depend(inout: x) ! { dg-message "'#pragma omp interop' not yet supported" }
|
!$omp interop nowait init (targetsync : obj1, obj2) use (obj3) destroy(obj4) init(target, targetsync : obj5) destroy(obj6) use(obj7) depend(inout: x)
|
||||||
! { dg-final { scan-tree-dump-times "#pragma omp interop depend\\(inout:x\\) init\\(targetsync: obj1\\) init\\(targetsync: obj2\\) init\\(target, targetsync: obj5\\) use\\(obj3\\) use\\(obj7\\) destroy\\(obj4\\) destroy\\(obj6\\) nowait\[\r\n\]" 1 "original" } }
|
! { dg-final { scan-tree-dump-times "#pragma omp interop depend\\(inout:x\\) init\\(targetsync: obj1\\) init\\(targetsync: obj2\\) init\\(target, targetsync: obj5\\) use\\(obj3\\) use\\(obj7\\) destroy\\(obj4\\) destroy\\(obj6\\) nowait\[\r\n\]" 1 "original" } }
|
||||||
|
|
||||||
!$omp interop init ( obj1, obj2) init (target: obj3) init(targetsync : obj4) init(target,targetsync: obj5) ! { dg-message "'#pragma omp interop' not yet supported" }
|
!$omp interop init ( obj1, obj2) init (target: obj3) init(targetsync : obj4) init(target,targetsync: obj5)
|
||||||
! { dg-final { scan-tree-dump-times "#pragma omp interop init\\(obj1\\) init\\(obj2\\) init\\(target: obj3\\) init\\(targetsync: obj4\\) init\\(target, targetsync: obj5\\)\[\r\n\]" 1 "original" } }
|
! { dg-final { scan-tree-dump-times "#pragma omp interop init\\(obj1\\) init\\(obj2\\) init\\(target: obj3\\) init\\(targetsync: obj4\\) init\\(target, targetsync: obj5\\)\[\r\n\]" 1 "original" } }
|
||||||
|
|
||||||
! --------------------------------------------
|
! --------------------------------------------
|
||||||
|
|
||||||
!$omp interop init (target, prefer_type(omp_ifr_cuda, omp_ifr_cuda+1, "hsa", "myPrivateInterop", omp_ifr_cuda-2) : obj1, obj2) init (target: obj3) init(prefer_type(omp_ifr_hip, "sycl", omp_ifr_opencl), targetsync : obj4, obj7) init(target,prefer_type("level_zero", omp_ifr_level_zero+0),targetsync: obj5) ! { dg-message "'#pragma omp interop' not yet supported" }
|
!$omp interop init (target, prefer_type(omp_ifr_cuda, omp_ifr_cuda+1, "hsa", "myPrivateInterop", omp_ifr_cuda-2) : obj1, obj2) init (target: obj3) init(prefer_type(omp_ifr_hip, "sycl", omp_ifr_opencl), targetsync : obj4, obj7) init(target,prefer_type("level_zero", omp_ifr_level_zero+0),targetsync: obj5)
|
||||||
!
|
!
|
||||||
! { dg-warning "Unknown foreign runtime identifier 'myPrivateInterop' at \\(1\\) \\\[-Wopenmp\\\]" "" { target *-*-* } .-2 }
|
! { dg-warning "Unknown foreign runtime identifier 'myPrivateInterop' at \\(1\\) \\\[-Wopenmp\\\]" "" { target *-*-* } .-2 }
|
||||||
! { dg-warning "Unknown foreign runtime identifier '-1' at \\(1\\) \\\[-Wopenmp\\\]" "" { target *-*-* } .-3 }
|
! { dg-warning "Unknown foreign runtime identifier '-1' at \\(1\\) \\\[-Wopenmp\\\]" "" { target *-*-* } .-3 }
|
||||||
|
|
@ -47,7 +47,7 @@ integer :: x(6)
|
||||||
|
|
||||||
! --------------------------------------------
|
! --------------------------------------------
|
||||||
|
|
||||||
!$omp interop init ( target, prefer_type( {fr(1_"hip"), attr("ompx_gnu_prio:1", 1_"ompx_gnu_debug")}, {attr("ompx_gnu_nicest"), attr("ompx_something")}) : obj1, obj2) init ( prefer_type( {fr("cuda")}, {fr(omp_ifr_cuda_driver), attr("ompx_nix")}, {fr("best")}), targetsync : obj3, obj4) nowait use(obj5) ! { dg-message "'#pragma omp interop' not yet supported" }
|
!$omp interop init ( target, prefer_type( {fr(1_"hip"), attr("ompx_gnu_prio:1", 1_"ompx_gnu_debug")}, {attr("ompx_gnu_nicest"), attr("ompx_something")}) : obj1, obj2) init ( prefer_type( {fr("cuda")}, {fr(omp_ifr_cuda_driver), attr("ompx_nix")}, {fr("best")}), targetsync : obj3, obj4) nowait use(obj5)
|
||||||
!
|
!
|
||||||
! ! { dg-warning "Unknown foreign runtime identifier 'best' at \\(1\\) \\\[-Wopenmp\\\]" "" { target *-*-* } .-2 }
|
! ! { dg-warning "Unknown foreign runtime identifier 'best' at \\(1\\) \\\[-Wopenmp\\\]" "" { target *-*-* } .-2 }
|
||||||
!
|
!
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
! { dg-additional-options "-fdump-tree-omplower" }
|
||||||
|
|
||||||
|
subroutine sub1 (a1, a2, a3, a4)
|
||||||
|
use omp_lib, only: omp_interop_kind
|
||||||
|
integer(omp_interop_kind) :: a1 ! by ref
|
||||||
|
integer(omp_interop_kind), optional :: a2 ! as pointer
|
||||||
|
integer(omp_interop_kind), allocatable :: a3 ! ref to pointer
|
||||||
|
integer(omp_interop_kind), value :: a4
|
||||||
|
integer(omp_interop_kind) :: b
|
||||||
|
|
||||||
|
!$omp interop init(target : a1, a2, a3, a4, b)
|
||||||
|
! { dg-final { scan-tree-dump-times "void \\* interopobjs\.\[0-9\]+\\\[5\\\];\[\r\n ]*integer\\(kind=4\\) tgt_tgtsync\.\[0-9\]+\\\[5\\\];\[\r\n ]*integer\\(kind=8\\) \\* & a3\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) \\* D\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) \\* a2\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) & a1\.\[0-9\]+;\[\r\n ]*interopobjs\.\[0-9\]+\\\[0\\\] = &b;\[\r\n ]*tgt_tgtsync\.\[0-9\]+\\\[0\\\] = 1;\[\r\n ]*interopobjs\.\[0-9\]+\\\[1\\\] = &a4;\[\r\n ]*tgt_tgtsync\.\[0-9\]+\\\[1\\\] = 1;\[\r\n ]*a3\.\[0-9\]+ = a3;\[\r\n ]*D\.\[0-9\]+ = \\*a3\.\[0-9\]+;\[\r\n ]*interopobjs\.\[0-9\]+\\\[2\\\] = D\.\[0-9\]+;\[\r\n ]*tgt_tgtsync\.\[0-9\]+\\\[2\\\] = 1;\[\r\n ]*a2\.\[0-9\]+ = a2;\[\r\n ]*interopobjs\.\[0-9\]+\\\[3\\\] = a2\.\[0-9\]+;\[\r\n ]*tgt_tgtsync\.\[0-9\]+\\\[3\\\] = 1;\[\r\n ]*a1\.\[0-9\]+ = a1;\[\r\n ]*interopobjs\.\[0-9\]+\\\[4\\\] = a1\.\[0-9\]+;\[\r\n ]*tgt_tgtsync\.\[0-9\]+\\\[4\\\] = 1;\[\r\n ]*__builtin_GOMP_interop \\(-5, 5, &interopobjs\.\[0-9\]+, &tgt_tgtsync\.\[0-9\]+, 0B, 0, 0B, 0, 0B, 0, 0B\\);" 1 "omplower" } }
|
||||||
|
|
||||||
|
!$omp interop use(a1, a2, a3, a4, b)
|
||||||
|
! { dg-final { scan-tree-dump-times "void \\* interopobjs\.\[0-9\]+\\\[5\\\];\[\r\n ]*integer\\(kind=8\\) b\.\[0-9\]+;\[\r\n ]*void \\* b\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) a4\.\[0-9\]+;\[\r\n ]*void \\* a4\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) \\* & a3\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) \\* D\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) D\.\[0-9\]+;\[\r\n ]*void \\* D\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) \\* a2\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) D\.\[0-9\]+;\[\r\n ]*void \\* D\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) & a1\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) D\.\[0-9\]+;\[\r\n ]*void \\* D\.\[0-9\]+;\[\r\n ]*b\.\[0-9\]+ = b;\[\r\n ]*b\.\[0-9\]+ = \\(void \\*\\) b\.\[0-9\]+;\[\r\n ]*interopobjs\.\[0-9\]+\\\[0\\\] = b\.\[0-9\]+;\[\r\n ]*a4\.\[0-9\]+ = a4;\[\r\n ]*a4\.\[0-9\]+ = \\(void \\*\\) a4\.\[0-9\]+;\[\r\n ]*interopobjs\.\[0-9\]+\\\[1\\\] = a4\.\[0-9\]+;\[\r\n ]*a3\.\[0-9\]+ = a3;\[\r\n ]*D\.\[0-9\]+ = \\*a3\.\[0-9\]+;\[\r\n ]*D\.\[0-9\]+ = \\*D\.\[0-9\]+;\[\r\n ]*D\.\[0-9\]+ = \\(void \\*\\) D\.\[0-9\]+;\[\r\n ]*interopobjs\.\[0-9\]+\\\[2\\\] = D\.\[0-9\]+;\[\r\n ]*a2\.\[0-9\]+ = a2;\[\r\n ]*D\.\[0-9\]+ = \\*a2\.\[0-9\]+;\[\r\n ]*D\.\[0-9\]+ = \\(void \\*\\) D\.\[0-9\]+;\[\r\n ]*interopobjs\.\[0-9\]+\\\[3\\\] = D\.\[0-9\]+;\[\r\n ]*a1\.\[0-9\]+ = a1;\[\r\n ]*D\.\[0-9\]+ = \\*a1\.\[0-9\]+;\[\r\n ]*D\.\[0-9\]+ = \\(void \\*\\) D\.\[0-9\]+;\[\r\n ]*interopobjs\.\[0-9\]+\\\[4\\\] = D\.\[0-9\]+;\[\r\n ]*__builtin_GOMP_interop \\(-5, 0, 0B, 0B, 0B, 5, &interopobjs\.\[0-9\]+, 0, 0B, 0, 0B\\);" 1 "omplower" } }
|
||||||
|
|
||||||
|
!$omp interop destroy(a1, a2, a3, a4, b)
|
||||||
|
! { dg-final { scan-tree-dump-times "void \\* interopobjs\.\[0-9\]+\\\[5\\\];\[\r\n ]*integer\\(kind=8\\) \\* & a3\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) \\* D\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) \\* a2\.\[0-9\]+;\[\r\n ]*integer\\(kind=8\\) & a1\.\[0-9\]+;\[\r\n ]*interopobjs\.\[0-9\]+\\\[0\\\] = &b;\[\r\n ]*interopobjs\.\[0-9\]+\\\[1\\\] = &a4;\[\r\n ]*a3\.\[0-9\]+ = a3;\[\r\n ]*D\.\[0-9\]+ = \\*a3\.\[0-9\]+;\[\r\n ]*interopobjs\.\[0-9\]+\\\[2\\\] = D\.\[0-9\]+;\[\r\n ]*a2\.\[0-9\]+ = a2;\[\r\n ]*interopobjs\.\[0-9\]+\\\[3\\\] = a2\.\[0-9\]+;\[\r\n ]*a1\.\[0-9\]+ = a1;\[\r\n ]*interopobjs\.\[0-9\]+\\\[4\\\] = a1\.\[0-9\]+;\[\r\n ]*__builtin_GOMP_interop \\(-5, 0, 0B, 0B, 0B, 0, 0B, 5, &interopobjs\.\[0-9\]+, 0, 0B\\);" 1 "omplower" } }
|
||||||
|
end subroutine
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,3 +1,12 @@
|
||||||
|
2025-03-21 Paul-Antoine Arras <parras@baylibre.com>
|
||||||
|
|
||||||
|
Backported from master:
|
||||||
|
2025-03-21 Paul-Antoine Arras <parras@baylibre.com>
|
||||||
|
Tobias Burnus <tburnus@baylibre.com>
|
||||||
|
|
||||||
|
* gomp-constants.h (GOMP_DEVICE_DEFAULT_OMP_61, GOMP_INTEROP_TARGET,
|
||||||
|
GOMP_INTEROP_TARGETSYNC, GOMP_INTEROP_FLAG_NOWAIT): Define.
|
||||||
|
|
||||||
2025-01-27 Tobias Burnus <tburnus@baylibre.com>
|
2025-01-27 Tobias Burnus <tburnus@baylibre.com>
|
||||||
|
|
||||||
Backported from master:
|
Backported from master:
|
||||||
|
|
|
||||||
|
|
@ -322,10 +322,14 @@ enum gomp_map_kind
|
||||||
omp_invalid_device) to -3 (so that for dev_num >= -2U we can
|
omp_invalid_device) to -3 (so that for dev_num >= -2U we can
|
||||||
subtract 1). -4 is then what we use for omp_invalid_device,
|
subtract 1). -4 is then what we use for omp_invalid_device,
|
||||||
which unlike the other non-conforming device numbers results
|
which unlike the other non-conforming device numbers results
|
||||||
in fatal error regardless of OMP_TARGET_OFFLOAD. */
|
in fatal error regardless of OMP_TARGET_OFFLOAD.
|
||||||
|
Furthermore, OpenMP 6.1 exposes the default device to the user; hence,
|
||||||
|
GOMP_DEVICE_DEFAULT_OMP_61 can be used for it,
|
||||||
|
with and without remapped device numbers. */
|
||||||
#define GOMP_DEVICE_ICV -1
|
#define GOMP_DEVICE_ICV -1
|
||||||
#define GOMP_DEVICE_HOST_FALLBACK -2
|
#define GOMP_DEVICE_HOST_FALLBACK -2
|
||||||
#define GOMP_DEVICE_INVALID -4
|
#define GOMP_DEVICE_INVALID -4
|
||||||
|
#define GOMP_DEVICE_DEFAULT_OMP_61 -5
|
||||||
|
|
||||||
/* GOMP_task/GOMP_taskloop* flags argument. */
|
/* GOMP_task/GOMP_taskloop* flags argument. */
|
||||||
#define GOMP_TASK_FLAG_UNTIED (1 << 0)
|
#define GOMP_TASK_FLAG_UNTIED (1 << 0)
|
||||||
|
|
@ -436,6 +440,13 @@ enum gomp_map_kind
|
||||||
#define GOMP_INTEROP_IFR_SEPARATOR ((char)(-__INT8_MAX__-1))
|
#define GOMP_INTEROP_IFR_SEPARATOR ((char)(-__INT8_MAX__-1))
|
||||||
#define GOMP_INTEROP_IFR_UNKNOWN ((char)(-__INT8_MAX__))
|
#define GOMP_INTEROP_IFR_UNKNOWN ((char)(-__INT8_MAX__))
|
||||||
|
|
||||||
|
/* GOMP_interop target_targetsync argument. */
|
||||||
|
#define GOMP_INTEROP_TARGET (1 << 0)
|
||||||
|
#define GOMP_INTEROP_TARGETSYNC (1 << 1)
|
||||||
|
|
||||||
|
/* GOMP_interop flags argument. */
|
||||||
|
#define GOMP_INTEROP_FLAG_NOWAIT (1 << 0)
|
||||||
|
|
||||||
/* HSA specific data structures. */
|
/* HSA specific data structures. */
|
||||||
|
|
||||||
/* Identifiers of device-specific target arguments. */
|
/* Identifiers of device-specific target arguments. */
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,35 @@
|
||||||
|
2025-03-21 Paul-Antoine Arras <parras@baylibre.com>
|
||||||
|
|
||||||
|
Backported from master:
|
||||||
|
2025-03-21 Paul-Antoine Arras <parras@baylibre.com>
|
||||||
|
Tobias Burnus <tburnus@baylibre.com>
|
||||||
|
|
||||||
|
* icv-device.c (omp_set_default_device): Check
|
||||||
|
GOMP_DEVICE_DEFAULT_OMP_61.
|
||||||
|
* libgomp-plugin.h (struct interop_obj_t): New.
|
||||||
|
(enum gomp_interop_flag): New.
|
||||||
|
(GOMP_OFFLOAD_interop): Declare.
|
||||||
|
(GOMP_OFFLOAD_get_interop_int): Declare.
|
||||||
|
(GOMP_OFFLOAD_get_interop_ptr): Declare.
|
||||||
|
(GOMP_OFFLOAD_get_interop_str): Declare.
|
||||||
|
(GOMP_OFFLOAD_get_interop_type_desc): Declare.
|
||||||
|
* libgomp.h (_LIBGOMP_OMP_LOCK_DEFINED): Define.
|
||||||
|
(struct gomp_device_descr): Add interop_func, get_interop_int_func,
|
||||||
|
get_interop_ptr_func, get_interop_str_func, get_interop_type_desc_func.
|
||||||
|
* libgomp.map: Add GOMP_interop.
|
||||||
|
* libgomp_g.h (GOMP_interop): Declare.
|
||||||
|
* target.c (resolve_device): Handle GOMP_DEVICE_DEFAULT_OMP_61.
|
||||||
|
(omp_get_interop_int): Replace stub with actual implementation.
|
||||||
|
(omp_get_interop_ptr): Likewise.
|
||||||
|
(omp_get_interop_str): Likewise.
|
||||||
|
(omp_get_interop_type_desc): Likewise.
|
||||||
|
(struct interop_data_t): Define.
|
||||||
|
(gomp_interop_internal): New function.
|
||||||
|
(GOMP_interop): Likewise.
|
||||||
|
(gomp_load_plugin_for_device): Load symbols for get_interop_int,
|
||||||
|
get_interop_ptr, get_interop_str and get_interop_type_desc.
|
||||||
|
* testsuite/libgomp.c-c++-common/interop-1.c: New test.
|
||||||
|
|
||||||
2025-03-18 Tobias Burnus <tburnus@baylibre.com>
|
2025-03-18 Tobias Burnus <tburnus@baylibre.com>
|
||||||
|
|
||||||
Backported from master:
|
Backported from master:
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,11 @@
|
||||||
void
|
void
|
||||||
omp_set_default_device (int device_num)
|
omp_set_default_device (int device_num)
|
||||||
{
|
{
|
||||||
struct gomp_task_icv *icv = gomp_icv (true);
|
if (device_num != GOMP_DEVICE_DEFAULT_OMP_61)
|
||||||
icv->default_device_var = device_num;
|
{
|
||||||
|
struct gomp_task_icv *icv = gomp_icv (true);
|
||||||
|
icv->default_device_var = device_num;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ialias (omp_set_default_device)
|
ialias (omp_set_default_device)
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,14 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef _LIBGOMP_PLUGIN_INCLUDE
|
||||||
|
/* Include 'omp.h' for the interop definitions. */
|
||||||
|
#define _LIBGOMP_OMP_LOCK_DEFINED 1
|
||||||
|
typedef struct omp_lock_t omp_lock_t;
|
||||||
|
typedef struct omp_nest_lock_t omp_nest_lock_t;
|
||||||
|
#include "omp.h.in"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -101,6 +109,25 @@ struct addr_pair
|
||||||
uintptr_t end;
|
uintptr_t end;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _LIBGOMP_OMP_LOCK_DEFINED
|
||||||
|
/* Only define when omp.h.in was included, as in plugin/ and in libgomp.h. */
|
||||||
|
struct interop_obj_t
|
||||||
|
{
|
||||||
|
void *stream;
|
||||||
|
void *device_data;
|
||||||
|
omp_interop_fr_t fr;
|
||||||
|
int device_num;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum gomp_interop_flag
|
||||||
|
{
|
||||||
|
gomp_interop_flag_init,
|
||||||
|
gomp_interop_flag_use,
|
||||||
|
gomp_interop_flag_destroy
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/* This following symbol is used to name the target side variable struct that
|
/* This following symbol is used to name the target side variable struct that
|
||||||
holds the designated ICVs of the target device. The symbol needs to be
|
holds the designated ICVs of the target device. The symbol needs to be
|
||||||
available to libgomp code and the offload plugin (which in the latter case
|
available to libgomp code and the offload plugin (which in the latter case
|
||||||
|
|
@ -185,6 +212,23 @@ extern int GOMP_OFFLOAD_openacc_cuda_set_stream (struct goacc_asyncqueue *,
|
||||||
extern union goacc_property_value
|
extern union goacc_property_value
|
||||||
GOMP_OFFLOAD_openacc_get_property (int, enum goacc_property);
|
GOMP_OFFLOAD_openacc_get_property (int, enum goacc_property);
|
||||||
|
|
||||||
|
#ifdef _LIBGOMP_OMP_LOCK_DEFINED
|
||||||
|
/* Only define when omp.h.in was included, as in plugin/ and in libgomp.h. */
|
||||||
|
extern void GOMP_OFFLOAD_interop (struct interop_obj_t *, int,
|
||||||
|
enum gomp_interop_flag, bool, const char *);
|
||||||
|
extern intptr_t GOMP_OFFLOAD_get_interop_int (struct interop_obj_t *,
|
||||||
|
omp_interop_property_t,
|
||||||
|
omp_interop_rc_t *);
|
||||||
|
extern void *GOMP_OFFLOAD_get_interop_ptr (struct interop_obj_t *,
|
||||||
|
omp_interop_property_t,
|
||||||
|
omp_interop_rc_t *);
|
||||||
|
extern const char *GOMP_OFFLOAD_get_interop_str (struct interop_obj_t *obj,
|
||||||
|
omp_interop_property_t,
|
||||||
|
omp_interop_rc_t *);
|
||||||
|
extern const char *GOMP_OFFLOAD_get_interop_type_desc (struct interop_obj_t *,
|
||||||
|
omp_interop_property_t);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,14 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* Include omp.h by parts. */
|
||||||
|
#include "omp-lock.h"
|
||||||
|
#define _LIBGOMP_OMP_LOCK_DEFINED 1
|
||||||
|
#include "omp.h.in"
|
||||||
|
|
||||||
#include "libgomp-plugin.h"
|
#include "libgomp-plugin.h"
|
||||||
|
|
||||||
#include "gomp-constants.h"
|
#include "gomp-constants.h"
|
||||||
|
|
||||||
#ifdef HAVE_PTHREAD_H
|
#ifdef HAVE_PTHREAD_H
|
||||||
|
|
@ -1440,6 +1447,11 @@ struct gomp_device_descr
|
||||||
__typeof (GOMP_OFFLOAD_run) *run_func;
|
__typeof (GOMP_OFFLOAD_run) *run_func;
|
||||||
__typeof (GOMP_OFFLOAD_async_run) *async_run_func;
|
__typeof (GOMP_OFFLOAD_async_run) *async_run_func;
|
||||||
__typeof (GOMP_OFFLOAD_evaluate_device) *evaluate_device_func;
|
__typeof (GOMP_OFFLOAD_evaluate_device) *evaluate_device_func;
|
||||||
|
__typeof (GOMP_OFFLOAD_interop) *interop_func;
|
||||||
|
__typeof (GOMP_OFFLOAD_get_interop_int) *get_interop_int_func;
|
||||||
|
__typeof (GOMP_OFFLOAD_get_interop_ptr) *get_interop_ptr_func;
|
||||||
|
__typeof (GOMP_OFFLOAD_get_interop_str) *get_interop_str_func;
|
||||||
|
__typeof (GOMP_OFFLOAD_get_interop_type_desc) *get_interop_type_desc_func;
|
||||||
|
|
||||||
/* Splay tree containing information about mapped memory regions. */
|
/* Splay tree containing information about mapped memory regions. */
|
||||||
struct splay_tree_s mem_map;
|
struct splay_tree_s mem_map;
|
||||||
|
|
@ -1523,11 +1535,6 @@ gomp_work_share_init_done (void)
|
||||||
/* Now that we're back to default visibility, include the globals. */
|
/* Now that we're back to default visibility, include the globals. */
|
||||||
#include "libgomp_g.h"
|
#include "libgomp_g.h"
|
||||||
|
|
||||||
/* Include omp.h by parts. */
|
|
||||||
#include "omp-lock.h"
|
|
||||||
#define _LIBGOMP_OMP_LOCK_DEFINED 1
|
|
||||||
#include "omp.h.in"
|
|
||||||
|
|
||||||
#if !defined (HAVE_ATTRIBUTE_VISIBILITY) \
|
#if !defined (HAVE_ATTRIBUTE_VISIBILITY) \
|
||||||
|| !defined (HAVE_ATTRIBUTE_ALIAS) \
|
|| !defined (HAVE_ATTRIBUTE_ALIAS) \
|
||||||
|| !defined (HAVE_AS_SYMVER_DIRECTIVE) \
|
|| !defined (HAVE_AS_SYMVER_DIRECTIVE) \
|
||||||
|
|
|
||||||
|
|
@ -432,6 +432,7 @@ GOMP_5.1.2 {
|
||||||
GOMP_5.1.3 {
|
GOMP_5.1.3 {
|
||||||
global:
|
global:
|
||||||
GOMP_evaluate_target_device;
|
GOMP_evaluate_target_device;
|
||||||
|
GOMP_interop;
|
||||||
omp_get_num_interop_properties;
|
omp_get_num_interop_properties;
|
||||||
omp_get_interop_int;
|
omp_get_interop_int;
|
||||||
omp_get_interop_ptr;
|
omp_get_interop_ptr;
|
||||||
|
|
|
||||||
|
|
@ -363,6 +363,10 @@ extern void GOMP_target_enter_exit_data (int, size_t, void **, size_t *,
|
||||||
extern void GOMP_teams (unsigned int, unsigned int);
|
extern void GOMP_teams (unsigned int, unsigned int);
|
||||||
extern bool GOMP_teams4 (unsigned int, unsigned int, unsigned int, bool);
|
extern bool GOMP_teams4 (unsigned int, unsigned int, unsigned int, bool);
|
||||||
extern void *GOMP_target_map_indirect_ptr (void *);
|
extern void *GOMP_target_map_indirect_ptr (void *);
|
||||||
|
struct interop_obj_t;
|
||||||
|
extern void GOMP_interop (int, int, struct interop_obj_t ***, const int *,
|
||||||
|
const char **, int, struct interop_obj_t **, int,
|
||||||
|
struct interop_obj_t ***, unsigned, void **);
|
||||||
|
|
||||||
extern bool GOMP_evaluate_target_device (int, const char *, const char *,
|
extern bool GOMP_evaluate_target_device (int, const char *, const char *,
|
||||||
const char *);
|
const char *);
|
||||||
|
|
|
||||||
213
libgomp/target.c
213
libgomp/target.c
|
|
@ -146,7 +146,8 @@ resolve_device (int device_id, bool remapped)
|
||||||
called, which must be done before using default_device_var. */
|
called, which must be done before using default_device_var. */
|
||||||
int num_devices = gomp_get_num_devices ();
|
int num_devices = gomp_get_num_devices ();
|
||||||
|
|
||||||
if (remapped && device_id == GOMP_DEVICE_ICV)
|
if ((remapped && device_id == GOMP_DEVICE_ICV)
|
||||||
|
|| device_id == GOMP_DEVICE_DEFAULT_OMP_61)
|
||||||
{
|
{
|
||||||
struct gomp_task_icv *icv = gomp_icv (false);
|
struct gomp_task_icv *icv = gomp_icv (false);
|
||||||
device_id = icv->default_device_var;
|
device_id = icv->default_device_var;
|
||||||
|
|
@ -5723,45 +5724,78 @@ omp_get_num_interop_properties (const omp_interop_t interop
|
||||||
}
|
}
|
||||||
|
|
||||||
omp_intptr_t
|
omp_intptr_t
|
||||||
omp_get_interop_int (const omp_interop_t interop __attribute__ ((unused)),
|
omp_get_interop_int (const omp_interop_t interop,
|
||||||
omp_interop_property_t property_id,
|
omp_interop_property_t property_id,
|
||||||
omp_interop_rc_t *ret_code)
|
omp_interop_rc_t *ret_code)
|
||||||
{
|
{
|
||||||
if (ret_code == NULL)
|
struct interop_obj_t *obj = (struct interop_obj_t *) interop;
|
||||||
return 0;
|
struct gomp_device_descr *devicep;
|
||||||
|
|
||||||
if (property_id < omp_ipr_first || property_id >= 0)
|
if (property_id < omp_ipr_first || property_id >= 0)
|
||||||
*ret_code = omp_irc_out_of_range;
|
{
|
||||||
else
|
if (ret_code)
|
||||||
*ret_code = omp_irc_empty; /* Assume omp_interop_none. */
|
*ret_code = omp_irc_out_of_range;
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
if (obj == NULL
|
||||||
|
|| (devicep = resolve_device (obj->device_num, false)) == NULL
|
||||||
|
|| devicep->get_interop_int_func == NULL)
|
||||||
|
{
|
||||||
|
if (ret_code)
|
||||||
|
*ret_code = omp_irc_empty; /* Assume omp_interop_none. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return devicep->get_interop_int_func (obj, property_id, ret_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
omp_get_interop_ptr (const omp_interop_t interop __attribute__ ((unused)),
|
omp_get_interop_ptr (const omp_interop_t interop,
|
||||||
omp_interop_property_t property_id,
|
omp_interop_property_t property_id,
|
||||||
omp_interop_rc_t *ret_code)
|
omp_interop_rc_t *ret_code)
|
||||||
{
|
{
|
||||||
if (ret_code == NULL)
|
struct interop_obj_t *obj = (struct interop_obj_t *) interop;
|
||||||
return NULL;
|
struct gomp_device_descr *devicep;
|
||||||
|
|
||||||
if (property_id < omp_ipr_first || property_id >= 0)
|
if (property_id < omp_ipr_first || property_id >= 0)
|
||||||
*ret_code = omp_irc_out_of_range;
|
{
|
||||||
else
|
if (ret_code)
|
||||||
*ret_code = omp_irc_empty; /* Assume omp_interop_none. */
|
*ret_code = omp_irc_out_of_range;
|
||||||
return NULL;
|
return 0;
|
||||||
|
}
|
||||||
|
if (obj == NULL
|
||||||
|
|| (devicep = resolve_device (obj->device_num, false)) == NULL
|
||||||
|
|| devicep->get_interop_int_func == NULL)
|
||||||
|
{
|
||||||
|
if (ret_code)
|
||||||
|
*ret_code = omp_irc_empty; /* Assume omp_interop_none. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return devicep->get_interop_ptr_func (obj, property_id, ret_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
omp_get_interop_str (const omp_interop_t interop __attribute__ ((unused)),
|
omp_get_interop_str (const omp_interop_t interop,
|
||||||
omp_interop_property_t property_id,
|
omp_interop_property_t property_id,
|
||||||
omp_interop_rc_t *ret_code)
|
omp_interop_rc_t *ret_code)
|
||||||
{
|
{
|
||||||
if (ret_code == NULL)
|
struct interop_obj_t *obj = (struct interop_obj_t *) interop;
|
||||||
return NULL;
|
struct gomp_device_descr *devicep;
|
||||||
|
|
||||||
if (property_id < omp_ipr_first || property_id >= 0)
|
if (property_id < omp_ipr_first || property_id >= 0)
|
||||||
*ret_code = omp_irc_out_of_range;
|
{
|
||||||
else
|
if (ret_code)
|
||||||
*ret_code = omp_irc_empty; /* Assume omp_interop_none. */
|
*ret_code = omp_irc_out_of_range;
|
||||||
return NULL;
|
return 0;
|
||||||
|
}
|
||||||
|
if (obj == NULL
|
||||||
|
|| (devicep = resolve_device (obj->device_num, false)) == NULL
|
||||||
|
|| devicep->get_interop_int_func == NULL)
|
||||||
|
{
|
||||||
|
if (ret_code)
|
||||||
|
*ret_code = omp_irc_empty; /* Assume omp_interop_none. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return devicep->get_interop_str_func (obj, property_id, ret_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
|
|
@ -5781,18 +5815,24 @@ omp_get_interop_type_desc (const omp_interop_t interop,
|
||||||
omp_interop_property_t property_id)
|
omp_interop_property_t property_id)
|
||||||
{
|
{
|
||||||
static const char *desc[omp_ipr_fr_id - omp_ipr_device_num + 1]
|
static const char *desc[omp_ipr_fr_id - omp_ipr_device_num + 1]
|
||||||
= {"omp_interop_t", /* fr_id */
|
= {"omp_interop_t", /* fr_id */
|
||||||
"const char*", /* fr_name */
|
"const char *", /* fr_name */
|
||||||
"int", /* vendor */
|
"int", /* vendor */
|
||||||
"const char *", /* vendor_name */
|
"const char *", /* vendor_name */
|
||||||
"int"}; /* device_num */
|
"int"}; /* device_num */
|
||||||
|
|
||||||
|
struct interop_obj_t *obj = (struct interop_obj_t *) interop;
|
||||||
|
struct gomp_device_descr *devicep;
|
||||||
|
|
||||||
if (property_id > omp_ipr_fr_id || property_id < omp_ipr_first)
|
if (property_id > omp_ipr_fr_id || property_id < omp_ipr_first)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (interop == omp_interop_none)
|
if (obj == NULL
|
||||||
|
|| (devicep = resolve_device (obj->device_num, false)) == NULL
|
||||||
|
|| devicep->get_interop_int_func == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (property_id >= omp_ipr_device_num)
|
if (property_id >= omp_ipr_device_num)
|
||||||
return desc[omp_ipr_fr_id - property_id];
|
return desc[omp_ipr_fr_id - property_id];
|
||||||
return NULL; /* FIXME: Call plugin. */
|
return devicep->get_interop_type_desc_func (obj, property_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
|
|
@ -5823,6 +5863,119 @@ ialias (omp_get_interop_name)
|
||||||
ialias (omp_get_interop_type_desc)
|
ialias (omp_get_interop_type_desc)
|
||||||
ialias (omp_get_interop_rc_desc)
|
ialias (omp_get_interop_rc_desc)
|
||||||
|
|
||||||
|
struct interop_data_t
|
||||||
|
{
|
||||||
|
int device_num, n_init, n_use, n_destroy;
|
||||||
|
struct interop_obj_t ***init;
|
||||||
|
struct interop_obj_t **use;
|
||||||
|
struct interop_obj_t ***destroy;
|
||||||
|
const int *target_targetsync;
|
||||||
|
const char **prefer_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
gomp_interop_internal (void *data)
|
||||||
|
{
|
||||||
|
struct interop_data_t *args = (struct interop_data_t *) data;
|
||||||
|
struct gomp_device_descr *devicep;
|
||||||
|
|
||||||
|
/* Destroy objects to free resources. */
|
||||||
|
for (int i = 0; i < args->n_destroy; i++)
|
||||||
|
{
|
||||||
|
struct interop_obj_t **obj = args->destroy[i];
|
||||||
|
if (*obj == NULL /* omp_interop_none */)
|
||||||
|
continue;
|
||||||
|
devicep = resolve_device ((*obj)->device_num, false);
|
||||||
|
if (devicep != NULL && devicep->interop_func)
|
||||||
|
devicep->interop_func (*obj, devicep->target_id,
|
||||||
|
gomp_interop_flag_destroy, false, NULL);
|
||||||
|
free (*obj);
|
||||||
|
*obj = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Init streams next to give 'use' more time for completion. */
|
||||||
|
if (args->n_init)
|
||||||
|
{
|
||||||
|
devicep = resolve_device (args->device_num, false);
|
||||||
|
for (int i = 0; i < args->n_init; i++)
|
||||||
|
{
|
||||||
|
struct interop_obj_t **obj = args->init[i];
|
||||||
|
bool targetsync
|
||||||
|
= (args->target_targetsync[i] & GOMP_INTEROP_TARGETSYNC);
|
||||||
|
const char *prefer_type
|
||||||
|
= (args->prefer_type ? args->prefer_type[i] : NULL);
|
||||||
|
if (devicep == NULL || !devicep->interop_func)
|
||||||
|
{
|
||||||
|
*obj = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*obj =
|
||||||
|
(struct interop_obj_t *) calloc (1, sizeof (struct interop_obj_t));
|
||||||
|
devicep->interop_func (*obj, devicep->target_id,
|
||||||
|
gomp_interop_flag_init, targetsync,
|
||||||
|
prefer_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < args->n_use; i++)
|
||||||
|
{
|
||||||
|
struct interop_obj_t *obj = args->use[i];
|
||||||
|
if (obj == NULL)
|
||||||
|
continue;
|
||||||
|
devicep = resolve_device (obj->device_num, false);
|
||||||
|
if (devicep != NULL && devicep->interop_func)
|
||||||
|
devicep->interop_func (obj, devicep->target_id,
|
||||||
|
gomp_interop_flag_use, false, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process the OpenMP interop directive. 'init' and 'destroy' take an array
|
||||||
|
of 'omp_interop_t *', 'use' an array of 'omp_interop_t', where
|
||||||
|
'omp_interop_t' is internally 'struct interop_obj_t *';
|
||||||
|
'flags' is used for the 'nowait' clause. */
|
||||||
|
|
||||||
|
void
|
||||||
|
GOMP_interop (int device_num, int n_init, struct interop_obj_t ***init,
|
||||||
|
const int *target_targetsync, const char **prefer_type, int n_use,
|
||||||
|
struct interop_obj_t **use, int n_destroy,
|
||||||
|
struct interop_obj_t ***destroy, unsigned int flags,
|
||||||
|
void **depend)
|
||||||
|
{
|
||||||
|
struct interop_data_t args;
|
||||||
|
args.device_num = device_num;
|
||||||
|
args.n_init = n_init;
|
||||||
|
args.n_use = n_use;
|
||||||
|
args.n_destroy = n_destroy;
|
||||||
|
args.init = init;
|
||||||
|
args.target_targetsync = target_targetsync;
|
||||||
|
args.prefer_type = prefer_type;
|
||||||
|
args.use = use;
|
||||||
|
args.destroy = destroy;
|
||||||
|
|
||||||
|
/* No need to create a task for 'init' as that should be fast. */
|
||||||
|
bool use_task = false;
|
||||||
|
if (flags & GOMP_INTEROP_FLAG_NOWAIT)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < n_use && !use_task; i++)
|
||||||
|
if (args.use[i])
|
||||||
|
use_task |= args.use[i]->stream != NULL;
|
||||||
|
for (int i = 0; i < n_destroy && !use_task; i++)
|
||||||
|
if (*args.destroy[i])
|
||||||
|
use_task |= (*args.destroy[i])->stream != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_task)
|
||||||
|
GOMP_task (gomp_interop_internal, &args, NULL, sizeof (args),
|
||||||
|
__alignof__ (args), true, depend ? GOMP_TASK_FLAG_DEPEND : 0,
|
||||||
|
depend, 0, NULL);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gomp_interop_internal (&args);
|
||||||
|
if (depend)
|
||||||
|
GOMP_taskwait_depend (depend);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
gomp_get_uid_for_device (struct gomp_device_descr *devicep, int device_num)
|
gomp_get_uid_for_device (struct gomp_device_descr *devicep, int device_num)
|
||||||
{
|
{
|
||||||
|
|
@ -5934,6 +6087,14 @@ gomp_load_plugin_for_device (struct gomp_device_descr *device,
|
||||||
DLSYM (evaluate_device);
|
DLSYM (evaluate_device);
|
||||||
DLSYM_OPT (memcpy2d, memcpy2d);
|
DLSYM_OPT (memcpy2d, memcpy2d);
|
||||||
DLSYM_OPT (memcpy3d, memcpy3d);
|
DLSYM_OPT (memcpy3d, memcpy3d);
|
||||||
|
if (DLSYM_OPT (interop, interop))
|
||||||
|
{
|
||||||
|
DLSYM (get_interop_int);
|
||||||
|
DLSYM (get_interop_ptr);
|
||||||
|
DLSYM (get_interop_str);
|
||||||
|
DLSYM (get_interop_type_desc);
|
||||||
|
}
|
||||||
|
|
||||||
device->capabilities = device->get_caps_func ();
|
device->capabilities = device->get_caps_func ();
|
||||||
if (device->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
|
if (device->capabilities & GOMP_OFFLOAD_CAP_OPENMP_400)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
/* { dg-do run } */
|
||||||
|
|
||||||
|
#include <omp.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
int dev = omp_get_num_devices ();
|
||||||
|
int x[6];
|
||||||
|
omp_interop_t obj1 = omp_interop_none;
|
||||||
|
#pragma omp interop init(targetsync : obj1) depend(in : x) device(dev)
|
||||||
|
if (obj1 != omp_interop_none)
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
#pragma omp interop use(obj1)
|
||||||
|
#pragma omp interop destroy(obj1) depend(out : x)
|
||||||
|
if (obj1 != omp_interop_none)
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
omp_set_default_device (dev);
|
||||||
|
omp_interop_t obj2;
|
||||||
|
|
||||||
|
#pragma omp interop init( \
|
||||||
|
target, targetsync, \
|
||||||
|
prefer_type({fr("hip"), attr("ompx_gnu_prio:1", "ompx_gnu_debug")}, \
|
||||||
|
{attr("ompx_gnu_nicest"), attr("ompx_something")}) : obj1, \
|
||||||
|
obj2) nowait
|
||||||
|
if (obj1 != omp_interop_none || obj2 != omp_interop_none)
|
||||||
|
abort ();
|
||||||
|
#pragma omp interop use(obj1, obj2) nowait
|
||||||
|
|
||||||
|
omp_interop_t obj3 = __omp_interop_t_max__;
|
||||||
|
|
||||||
|
#pragma omp interop init(target : obj3) use(obj2) destroy(obj1) nowait
|
||||||
|
if (obj1 != omp_interop_none || obj3 != omp_interop_none)
|
||||||
|
abort ();
|
||||||
|
#pragma omp interop destroy(obj3, obj2) nowait
|
||||||
|
if (obj2 != omp_interop_none || obj3 != omp_interop_none)
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue