diff options
author | Paul-Antoine Arras <parras@baylibre.com> | 2025-03-13 17:16:41 +0100 |
---|---|---|
committer | Paul-Antoine Arras <parras@baylibre.com> | 2025-03-21 19:24:16 +0100 |
commit | 99e2906ae255fc7b8edb008d7cd47b28b078a809 (patch) | |
tree | aa20eea780d8962d8be0da6122795911e7376390 /gcc | |
parent | f45d14b495d603b8d5fbdffe6fced03cb3e2fc10 (diff) | |
download | gcc-99e2906ae255fc7b8edb008d7cd47b28b078a809.zip gcc-99e2906ae255fc7b8edb008d7cd47b28b078a809.tar.gz gcc-99e2906ae255fc7b8edb008d7cd47b28b078a809.tar.bz2 |
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>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/builtin-types.def | 3 | ||||
-rw-r--r-- | gcc/c/c-parser.cc | 6 | ||||
-rw-r--r-- | gcc/cp/parser.cc | 1 | ||||
-rw-r--r-- | gcc/fortran/trans-openmp.cc | 20 | ||||
-rw-r--r-- | gcc/fortran/types.def | 3 | ||||
-rw-r--r-- | gcc/gimple-low.cc | 1 | ||||
-rw-r--r-- | gcc/gimple-pretty-print.cc | 23 | ||||
-rw-r--r-- | gcc/gimple.cc | 18 | ||||
-rw-r--r-- | gcc/gimple.def | 4 | ||||
-rw-r--r-- | gcc/gimple.h | 33 | ||||
-rw-r--r-- | gcc/gimplify.cc | 22 | ||||
-rw-r--r-- | gcc/omp-builtins.def | 3 | ||||
-rw-r--r-- | gcc/omp-low.cc | 233 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/gomp/interop-1.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/gomp/interop-2.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/gomp/interop-3.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/gomp/interop-4.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/gomp/interop-5.c | 68 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/gomp/interop-5.C | 12 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/gomp/interop-4.f90 | 10 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/gomp/interop-5.f90 | 21 |
21 files changed, 467 insertions, 32 deletions
diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def index 9b7cc99..9583d30 100644 --- a/gcc/builtin-types.def +++ b/gcc/builtin-types.def @@ -1015,6 +1015,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_UINT, BT_LONG, BT_INT, 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_INT_VAR, BT_INT) diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index d49d5c5..cfb1f60 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -20519,7 +20519,10 @@ c_parser_omp_clause_detach (c_parser *parser, tree list) static tree 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: @@ -20901,6 +20904,7 @@ c_parser_omp_clause_init (c_parser *parser, tree list) for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) { + TREE_ADDRESSABLE (OMP_CLAUSE_DECL (c)) = 1; if (target) OMP_CLAUSE_INIT_TARGET (c) = 1; if (targetsync) diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 2fb1dc5..57a4610 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -43183,6 +43183,7 @@ cp_parser_omp_clause_init (cp_parser *parser, tree list) NULL, false); for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) { + TREE_ADDRESSABLE (OMP_CLAUSE_DECL (c)) = 1; if (target) OMP_CLAUSE_INIT_TARGET (c) = 1; if (targetsync) diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc index d1c05d0..bf8c341 100644 --- a/gcc/fortran/trans-openmp.cc +++ b/gcc/fortran/trans-openmp.cc @@ -2790,9 +2790,6 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, case OMP_LIST_USE: clause_code = OMP_CLAUSE_USE; goto add_clause; - case OMP_LIST_DESTROY: - clause_code = OMP_CLAUSE_DESTROY; - goto add_clause; case OMP_LIST_INTEROP: clause_code = OMP_CLAUSE_INTEROP; goto add_clause; @@ -2803,6 +2800,22 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, declare_simd); 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: { tree pref_type = NULL_TREE; @@ -2816,6 +2829,7 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, tree node = build_omp_clause (input_location, OMP_CLAUSE_INIT); OMP_CLAUSE_DECL (node) = t; + TREE_ADDRESSABLE (OMP_CLAUSE_DECL (node)) = 1; if (n->u.init.target) OMP_CLAUSE_INIT_TARGET (node) = 1; if (n->u.init.targetsync) diff --git a/gcc/fortran/types.def b/gcc/fortran/types.def index 6447cee..dd9b8df 100644 --- a/gcc/fortran/types.def +++ b/gcc/fortran/types.def @@ -266,6 +266,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_UINT, BT_LONG, BT_INT, 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) diff --git a/gcc/gimple-low.cc b/gcc/gimple-low.cc index 26b415c..b612970 100644 --- a/gcc/gimple-low.cc +++ b/gcc/gimple-low.cc @@ -747,6 +747,7 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data) case GIMPLE_OMP_FOR: case GIMPLE_OMP_SCOPE: case GIMPLE_OMP_DISPATCH: + case GIMPLE_OMP_INTEROP: case GIMPLE_OMP_SECTIONS: case GIMPLE_OMP_SECTIONS_SWITCH: case GIMPLE_OMP_SECTION: diff --git a/gcc/gimple-pretty-print.cc b/gcc/gimple-pretty-print.cc index d1531fc..4e20b4c 100644 --- a/gcc/gimple-pretty-print.cc +++ b/gcc/gimple-pretty-print.cc @@ -1755,6 +1755,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 PP. */ static void @@ -2838,6 +2857,10 @@ pp_gimple_stmt_1 (pretty_printer *pp, const gimple *gs, int spc, dump_gimple_omp_dispatch(pp, gs, spc, flags); break; + case GIMPLE_OMP_INTEROP: + dump_gimple_omp_interop (pp, gs, spc, flags); + break; + case GIMPLE_OMP_MASTER: case GIMPLE_OMP_SECTION: case GIMPLE_OMP_STRUCTURED_BLOCK: diff --git a/gcc/gimple.cc b/gcc/gimple.cc index 9a58a3a..9acfa38 100644 --- a/gcc/gimple.cc +++ b/gcc/gimple.cc @@ -1278,6 +1278,19 @@ gimple_build_omp_dispatch (gimple_seq body, tree clauses) 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. BODY is the sequence of statements that will be executed. @@ -2205,6 +2218,11 @@ gimple_copy (gimple *stmt) gimple_omp_dispatch_set_clauses (copy, t); 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: { gomp_target *omp_target_stmt = as_a <gomp_target *> (stmt); diff --git a/gcc/gimple.def b/gcc/gimple.def index 609c711..54248a8 100644 --- a/gcc/gimple.def +++ b/gcc/gimple.def @@ -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. */ 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. BODY is the sequence of statements in the section body. */ DEFGSCODE(GIMPLE_OMP_SECTION, "gimple_omp_section", GSS_OMP) diff --git a/gcc/gimple.h b/gcc/gimple.h index ecbd54c..112e5ae 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -745,7 +745,8 @@ struct GTY((tag("GSS_OMP_CONTINUE"))) }; /* 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"))) gimple_statement_omp_single_layout : public gimple_statement_omp @@ -1595,6 +1596,7 @@ gimple *gimple_build_omp_section (gimple_seq); gimple *gimple_build_omp_structured_block (gimple_seq); gimple *gimple_build_omp_scope (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_masked (gimple_seq, tree); gimple *gimple_build_omp_taskgroup (gimple_seq, tree); @@ -5468,6 +5470,34 @@ gimple_omp_dispatch_set_clauses (gimple *gs, tree 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. */ inline int @@ -6802,6 +6832,7 @@ gimple_return_set_retval (greturn *gs, tree retval) case GIMPLE_OMP_TEAMS: \ case GIMPLE_OMP_SCOPE: \ case GIMPLE_OMP_DISPATCH: \ + case GIMPLE_OMP_INTEROP: \ case GIMPLE_OMP_SECTION: \ case GIMPLE_OMP_STRUCTURED_BLOCK: \ case GIMPLE_OMP_MASTER: \ diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc index 5bdd970..244c4ba 100644 --- a/gcc/gimplify.cc +++ b/gcc/gimplify.cc @@ -13853,6 +13853,9 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, case OMP_CLAUSE_IF_PRESENT: case OMP_CLAUSE_FINALIZE: case OMP_CLAUSE_INTEROP: + case OMP_CLAUSE_INIT: + case OMP_CLAUSE_USE: + case OMP_CLAUSE_DESTROY: break; case OMP_CLAUSE_ORDER: @@ -18480,6 +18483,21 @@ gimplify_omp_ordered (tree expr, gimple_seq body) return gimple_build_omp_ordered (body, OMP_ORDERED_CLAUSES (expr)); } +/* 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; +} + /* Callback for walk_tree to find an IFN_GOMP_DISPATCH. */ static tree @@ -19953,9 +19971,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, } case OMP_INTEROP: - sorry_at (EXPR_LOCATION (*expr_p), - "%<#pragma omp interop%> not yet supported"); - ret = GS_ERROR; + ret = gimplify_omp_interop (expr_p, pre_p); break; case OMP_ATOMIC: case OMP_ATOMIC_READ: diff --git a/gcc/omp-builtins.def b/gcc/omp-builtins.def index 96de707..f73fb7b 100644 --- a/gcc/omp-builtins.def +++ b/gcc/omp-builtins.def @@ -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) DEF_GOMP_BUILTIN (BUILT_IN_GOMP_DOACROSS_ULL_WAIT, "GOMP_doacross_ull_wait", 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", BT_FN_VOID_OMPFN_PTR_UINT_UINT, ATTR_NOTHROW_LIST) DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_REDUCTIONS, diff --git a/gcc/omp-low.cc b/gcc/omp-low.cc index c36ae38..e369df6 100644 --- a/gcc/omp-low.cc +++ b/gcc/omp-low.cc @@ -1790,6 +1790,11 @@ scan_sharing_clauses (tree clauses, omp_context *ctx) install_var_local (decl, ctx); break; + case OMP_CLAUSE_INIT: + case OMP_CLAUSE_USE: + case OMP_CLAUSE_DESTROY: + break; + case OMP_CLAUSE__CACHE_: case OMP_CLAUSE_NOHOST: default: @@ -1986,6 +1991,9 @@ scan_sharing_clauses (tree clauses, omp_context *ctx) case OMP_CLAUSE_FINALIZE: case OMP_CLAUSE_FILTER: case OMP_CLAUSE__CONDTEMP_: + case OMP_CLAUSE_INIT: + case OMP_CLAUSE_USE: + case OMP_CLAUSE_DESTROY: break; case OMP_CLAUSE__CACHE_: @@ -4211,6 +4219,10 @@ scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p, scan_omp (gimple_omp_body_ptr (stmt), ctx); break; + case GIMPLE_OMP_INTEROP: + ctx = new_omp_context (stmt, ctx); + break; + case GIMPLE_OMP_SECTIONS: scan_omp_sections (as_a <gomp_sections *> (stmt), ctx); break; @@ -14331,6 +14343,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. */ static void @@ -14614,6 +14842,11 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx) gcc_assert (ctx); lower_omp_dispatch (gsi_p, ctx); break; + case GIMPLE_OMP_INTEROP: + ctx = maybe_lookup_ctx (stmt); + gcc_assert (ctx); + lower_omp_interop (gsi_p, ctx); + break; case GIMPLE_OMP_SINGLE: ctx = maybe_lookup_ctx (stmt); gcc_assert (ctx); diff --git a/gcc/testsuite/c-c++-common/gomp/interop-1.c b/gcc/testsuite/c-c++-common/gomp/interop-1.c index de3a4ba..d68611b 100644 --- a/gcc/testsuite/c-c++-common/gomp/interop-1.c +++ b/gcc/testsuite/c-c++-common/gomp/interop-1.c @@ -2,8 +2,6 @@ /* { dg-additional-options "-std=c23" { target c } } */ /* 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 in gcc/testsuite/ */ diff --git a/gcc/testsuite/c-c++-common/gomp/interop-2.c b/gcc/testsuite/c-c++-common/gomp/interop-2.c index 57fd688d..af81cc6 100644 --- a/gcc/testsuite/c-c++-common/gomp/interop-2.c +++ b/gcc/testsuite/c-c++-common/gomp/interop-2.c @@ -2,8 +2,6 @@ /* { dg-additional-options "-std=c23" { target c } } */ /* 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 in gcc/testsuite/ */ diff --git a/gcc/testsuite/c-c++-common/gomp/interop-3.c b/gcc/testsuite/c-c++-common/gomp/interop-3.c index 42478bf..51d26dd 100644 --- a/gcc/testsuite/c-c++-common/gomp/interop-3.c +++ b/gcc/testsuite/c-c++-common/gomp/interop-3.c @@ -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 in gcc/testsuite/ */ diff --git a/gcc/testsuite/c-c++-common/gomp/interop-4.c b/gcc/testsuite/c-c++-common/gomp/interop-4.c index 1f9c987..bb0bf31 100644 --- a/gcc/testsuite/c-c++-common/gomp/interop-4.c +++ b/gcc/testsuite/c-c++-common/gomp/interop-4.c @@ -33,18 +33,18 @@ f() omp_interop_t obj1, obj2, obj3, obj4, obj5, obj6, obj7; 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" } } */ - #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" } } */ - #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" } } */ /* -------------------------------------------- */ - #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 '-1' \\\[-Wopenmp\\\]" "" { target *-*-* } .-3 } @@ -55,7 +55,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 } @@ -69,7 +69,7 @@ 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-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" } } */ } diff --git a/gcc/testsuite/c-c++-common/gomp/interop-5.c b/gcc/testsuite/c-c++-common/gomp/interop-5.c new file mode 100644 index 0000000..0b9bd09 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/interop-5.c @@ -0,0 +1,68 @@ +/* { 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++ } } } */ +} diff --git a/gcc/testsuite/g++.dg/gomp/interop-5.C b/gcc/testsuite/g++.dg/gomp/interop-5.C index 5109dc4..89396cf 100644 --- a/gcc/testsuite/g++.dg/gomp/interop-5.C +++ b/gcc/testsuite/g++.dg/gomp/interop-5.C @@ -1,8 +1,6 @@ /* { dg-do compile { target c++11 } } */ /* { 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 in gcc/testsuite/ */ @@ -43,13 +41,13 @@ f () constexpr T3 ifr_level_zero = (T3) (omp_ifr_sycl + 2); 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" } } */ - #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" } } */ - #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" } } */ /* -------------------------------------------- */ @@ -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" } } */ - #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 '-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 } diff --git a/gcc/testsuite/gfortran.dg/gomp/interop-4.f90 b/gcc/testsuite/gfortran.dg/gomp/interop-4.f90 index 8783f4c..43c28d6 100644 --- a/gcc/testsuite/gfortran.dg/gomp/interop-4.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/interop-4.f90 @@ -26,18 +26,18 @@ implicit none integer(omp_interop_kind) :: obj1, obj2, obj3, obj4, obj5, obj6, obj7 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" } } -!$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" } } -!$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" } } ! -------------------------------------------- -!$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 '-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 } ! diff --git a/gcc/testsuite/gfortran.dg/gomp/interop-5.f90 b/gcc/testsuite/gfortran.dg/gomp/interop-5.f90 new file mode 100644 index 0000000..a6a2d71 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/interop-5.f90 @@ -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 + + |