diff options
author | Tobias Burnus <tburnus@baylibre.com> | 2024-11-22 15:30:53 +0100 |
---|---|---|
committer | Tobias Burnus <tburnus@baylibre.com> | 2024-11-22 15:30:53 +0100 |
commit | 8f0c8e577a56891fa104c818834ddafe268722bb (patch) | |
tree | b23eca9aa95f8ff60434daabf5c57a08baf953dd /gcc/fortran/trans-openmp.cc | |
parent | 8d7f2d53c81970c50a4b9bc592ce360563ae192b (diff) | |
download | gcc-8f0c8e577a56891fa104c818834ddafe268722bb.zip gcc-8f0c8e577a56891fa104c818834ddafe268722bb.tar.gz gcc-8f0c8e577a56891fa104c818834ddafe268722bb.tar.bz2 |
OpenMP: 'interop' construct - add C/C++ parser support, improve Fortran parsing
Add middle end support for the 'interop' directive and the 'init', 'use',
and 'destroy' clauses - but fail with a sorry, unimplemented in gimplify.cc.
For Fortran, generate the tree code, update the internal representation,
add some more diagnostic checks and update for newer specification changes
('fr' only takes a single value, but it integer expressions are permitted
again [like with the old syntax] not only constant identifiers).
For C and C++, this patch adds the full parser support for 'interop'.
Still missing is actually handling the directive in the middle end and
in libgomp.
The GOMP_INTEROP_IFR_* internal values have been changed to have space
for vendor specific values that are adjacent to the existing values
but negative, if needed.
gcc/c-family/ChangeLog:
* c-common.h (enum c_omp_region_type): Add C_ORT_INTEROP
and C_ORT_OMP_INTEROP.
(c_omp_interop_t_p): New prototype.
* c-omp.cc (c_omp_interop_t_p): Check whether the type is
omp_interop_t.
(c_omp_directives): Uncomment 'interop'.
* c-pragma.cc (omp_pragmas): Add 'interop'.
* c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_INTEROP.
(enum pragma_omp_clause): Add init, use, and destroy clauses.
gcc/c/ChangeLog:
* c-parser.cc (INCLUDE_STRING): Define.
(c_parser_pragma): Handle 'interop' directive.
(c_parser_omp_clause_name): Handle init, use, and destroy clauses.
(c_parser_omp_all_clauses): Likewise; use C_ORT_OMP_INTEROP, if
'use' is permitted, for c_finish_omp_clauses.
(c_parser_omp_clause_destroy, c_parser_omp_modifier_prefer_type,
c_parser_omp_clause_init, c_parser_omp_clause_use,
OMP_INTEROP_CLAUSE_MASK, c_parser_omp_interop): New.
* c-typeck.cc (c_finish_omp_clauses): Add missing OPT_Wopenmp to
a warning; handle new clauses.
gcc/cp/ChangeLog:
* parser.cc (INCLUDE_STRING): Define.
(cp_parser_omp_clause_name): Handle init, use, and destroy clauses.
(cp_parser_omp_all_clauses): Likewise; use C_ORT_OMP_INTEROP, if
'use' is permitted, for c_finish_omp_clauses.
(cp_parser_omp_modifier_prefer_type, cp_parser_omp_clause_init,
OMP_INTEROP_CLAUSE_MASK, cp_parser_omp_interop): New.
(cp_parser_pragma): Handle 'interop' directive.
* pt.cc (tsubst_omp_clauses): Handle init, use, and destroy clauses.
(tsubst_stmt): Handle OMP_INTEROP.
* semantics.cc (cp_omp_init_prefer_type_update): New.
(finish_omp_clauses): Handle init, use, and destroy clauses
and add clause check for 'depend' on 'interop'.
gcc/fortran/ChangeLog:
* gfortran.h (gfc_omp_namelist): Cleanup interop internal
representation.
* dump-parse-tree.cc (show_omp_namelist): Update for changed
internal representation.
* match.cc (gfc_free_omp_namelist): Likewise.
* openmp.cc (gfc_match_omp_prefer_type, gfc_match_omp_init):
Likewise; also handle some corner cases better and update for
newer 6.0 changes related to 'fr'.
(resolve_omp_clauses): Add type-check for interop variables.
* trans-openmp.cc (gfc_trans_omp_clauses): Handle init, use
and destroy clauses.
(gfc_trans_openmp_interop): New.
(gfc_trans_omp_directive): Call it.
gcc/ChangeLog:
* gimplify.cc (gimplify_expr): Handle OMP_INTEROP by printing
"sorry, uninplemented".
* omp-api.h (omp_get_fr_id_from_name): Change return type to
'char'.
* omp-general.cc (omp_get_fr_id_from_name): Likewise; return
GOMP_INTEROP_IFR_UNKNOWN not 0 if not found.
(omp_get_name_from_fr_id): Return "<unknown>" not NULL
if not found (used for dumps).
* tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_DESTROY,
OMP_CLAUSE_USE, and OMP_CLAUSE_INIT.
* tree-pretty-print.cc (dump_omp_init_prefer_type): New.
(dump_omp_clause): Handle init, use and destroy clauses.
(dump_generic_node): Handle interop directive.
* tree.cc (omp_clause_num_ops, omp_clause_code_name): Add new
init/use/destroy clauses.
* tree.def (OACC_LOOP): Fix comment.
(OMP_INTEROP): Add.
* tree.h (OMP_INTEROP_CLAUSES, OMP_CLAUSE_INIT_TARGET,
OMP_CLAUSE_INIT_TARGETSYNC, OMP_CLAUSE_INIT_PREFER_TYPE): New.
include/ChangeLog:
* gomp-constants.h (GOMP_INTEROP_IFR_NONE): Rename ...
(GOMP_INTEROP_IFR_UNKNOWN): ... to this. And change value.
(GOMP_INTEROP_IFR_SEPARATOR): Likewise.
gcc/testsuite/ChangeLog:
* gfortran.dg/gomp/interop-1.f90: Update for parser changes,
spec changes and add new tests.
* gfortran.dg/gomp/interop-2.f90: Likewise.
* gfortran.dg/gomp/interop-3.f90: Likewise.
* c-c++-common/gomp/interop-1.c: New test.
* c-c++-common/gomp/interop-2.c: New test.
* c-c++-common/gomp/interop-3.c: New test.
* c-c++-common/gomp/interop-4.c: New test.
* g++.dg/gomp/interop-5.C: New test.
* gfortran.dg/gomp/interop-4.f90: New test.
Diffstat (limited to 'gcc/fortran/trans-openmp.cc')
-rw-r--r-- | gcc/fortran/trans-openmp.cc | 59 |
1 files changed, 57 insertions, 2 deletions
diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc index 6c2c7482..4f4b408 100644 --- a/gcc/fortran/trans-openmp.cc +++ b/gcc/fortran/trans-openmp.cc @@ -2775,12 +2775,56 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, case OMP_LIST_SCAN_EX: clause_code = OMP_CLAUSE_EXCLUSIVE; goto add_clause; + case OMP_LIST_USE: + clause_code = OMP_CLAUSE_USE; + goto add_clause; + case OMP_LIST_DESTROY: + clause_code = OMP_CLAUSE_DESTROY; + goto add_clause; add_clause: omp_clauses = gfc_trans_omp_variable_list (clause_code, n, omp_clauses, declare_simd); break; + + case OMP_LIST_INIT: + { + tree pref_type = NULL_TREE; + const char *last = NULL; + for (; n != NULL; n = n->next) + if (n->sym->attr.referenced) + { + tree t = gfc_trans_omp_variable (n->sym, false); + if (t == error_mark_node) + continue; + tree node = build_omp_clause (input_location, + OMP_CLAUSE_INIT); + OMP_CLAUSE_DECL (node) = t; + if (n->u.init.target) + OMP_CLAUSE_INIT_TARGET (node) = 1; + if (n->u.init.targetsync) + OMP_CLAUSE_INIT_TARGETSYNC (node) = 1; + if (last != n->u2.init_interop) + { + last = n->u2.init_interop; + if (n->u2.init_interop == NULL) + pref_type = NULL_TREE; + else + { + pref_type = build_string (n->u.init.len, + n->u2.init_interop); + TREE_TYPE (pref_type) + = build_array_type_nelts (unsigned_char_type_node, + n->u.init.len); + } + } + OMP_CLAUSE_INIT_PREFER_TYPE (node) = pref_type; + omp_clauses = gfc_trans_add_clause (node, omp_clauses); + } + break; + } + case OMP_LIST_ALIGNED: for (; n != NULL; n = n->next) if (n->sym->attr.referenced || declare_simd) @@ -8028,6 +8072,18 @@ gfc_trans_omp_target_update (gfc_code *code) } static tree +gfc_trans_openmp_interop (gfc_code *code, gfc_omp_clauses *clauses) +{ + stmtblock_t block; + gfc_start_block (&block); + tree omp_clauses = gfc_trans_omp_clauses (&block, clauses, code->loc); + tree stmt = build1_loc (input_location, OMP_INTEROP, void_type_node, + omp_clauses); + gfc_add_expr_to_block (&block, stmt); + return gfc_finish_block (&block); +} + +static tree gfc_trans_omp_workshare (gfc_code *code, gfc_omp_clauses *clauses) { tree res, tmp, stmt; @@ -8365,8 +8421,7 @@ gfc_trans_omp_directive (gfc_code *code) case EXEC_OMP_WORKSHARE: return gfc_trans_omp_workshare (code, code->ext.omp_clauses); case EXEC_OMP_INTEROP: - sorry ("%<!$OMP INTEROP%>"); - return build_empty_stmt (input_location); + return gfc_trans_openmp_interop (code, code->ext.omp_clauses); default: gcc_unreachable (); } |