[Patch] OpenMP/Fortran: Add support for OpenMP 5.2 linear clause syntax
This patch adds support for the OpenMP 5.2 syntax for the linear clause, following the C/C++ patch. The testcases are modified versions from the C/C++ ones, plus one added one for duplicated modifiers. At least to me it is not quite clear when linear ( var : ref) refers to a variable 'ref' and when to the linear-modifier 'ref'; the spec does not seem to be very clear about it. I made an attempt, based on the C/C++ code – but I am not positive I handle it correctly. Tested on x86-64-gnu-linux. OK? Or are there comments? Tobias - Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955 OpenMP/Fortran: Add support for OpenMP 5.2 linear clause syntax Fortran part to C/C++ commit r13-1002-g03b71406323ddc065b1d7837d8b43b17e4b048b5 gcc/fortran/ChangeLog: * gfortran.h (gfc_omp_namelist): Update by creating 'linear' struct, move 'linear_op' as 'op' to id and add 'old_modifier' to it. * dump-parse-tree.cc (show_omp_namelist): Update accordingly. * module.cc (mio_omp_declare_simd): Likewise. * trans-openmp.cc (gfc_trans_omp_clauses): Likewise. * openmp.cc (resolve_omp_clauses): Likewise; accept new-style 'val' modifier with do/simd. (gfc_match_omp_clauses): Handle OpenMP 5.2 linear clause syntax. libgomp/ChangeLog: * libgomp.texi (OpenMP 5.2): Mark linear-clause change as 'Y'. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/linear-2.f90: New test. * gfortran.dg/gomp/linear-3.f90: New test. * gfortran.dg/gomp/linear-4.f90: New test. * gfortran.dg/gomp/linear-5.f90: New test. * gfortran.dg/gomp/linear-6.f90: New test. * gfortran.dg/gomp/linear-7.f90: New test. gcc/fortran/dump-parse-tree.cc | 6 +- gcc/fortran/gfortran.h | 6 +- gcc/fortran/module.cc | 6 +- gcc/fortran/openmp.cc | 232 +--- gcc/fortran/trans-openmp.cc | 5 +- gcc/testsuite/gfortran.dg/gomp/linear-2.f90 | 112 ++ gcc/testsuite/gfortran.dg/gomp/linear-3.f90 | 39 + gcc/testsuite/gfortran.dg/gomp/linear-4.f90 | 102 gcc/testsuite/gfortran.dg/gomp/linear-5.f90 | 43 ++ gcc/testsuite/gfortran.dg/gomp/linear-6.f90 | 54 +++ gcc/testsuite/gfortran.dg/gomp/linear-7.f90 | 27 libgomp/libgomp.texi| 2 +- 12 files changed, 604 insertions(+), 30 deletions(-) diff --git a/gcc/fortran/dump-parse-tree.cc b/gcc/fortran/dump-parse-tree.cc index 85c0b98f615..5352008a63d 100644 --- a/gcc/fortran/dump-parse-tree.cc +++ b/gcc/fortran/dump-parse-tree.cc @@ -1421,8 +1421,8 @@ show_omp_namelist (int list_type, gfc_omp_namelist *n) case OMP_MAP_RELEASE: fputs ("release:", dumpfile); break; default: break; } - else if (list_type == OMP_LIST_LINEAR) - switch (n->u.linear_op) + else if (list_type == OMP_LIST_LINEAR && n->u.linear.old_modifier) + switch (n->u.linear.op) { case OMP_LINEAR_REF: fputs ("ref(", dumpfile); break; case OMP_LINEAR_VAL: fputs ("val(", dumpfile); break; @@ -1430,7 +1430,7 @@ show_omp_namelist (int list_type, gfc_omp_namelist *n) default: break; } fprintf (dumpfile, "%s", n->sym ? n->sym->name : "omp_all_memory"); - if (list_type == OMP_LIST_LINEAR && n->u.linear_op != OMP_LINEAR_DEFAULT) + if (list_type == OMP_LIST_LINEAR && n->u.linear.op != OMP_LINEAR_DEFAULT) fputc (')', dumpfile); if (n->expr) { diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 463d9692236..696aadd7db6 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1345,7 +1345,11 @@ typedef struct gfc_omp_namelist gfc_omp_reduction_op reduction_op; gfc_omp_depend_op depend_op; gfc_omp_map_op map_op; - gfc_omp_linear_op linear_op; + struct + { + ENUM_BITFIELD (gfc_omp_linear_op) op:4; + bool old_modifier; + } linear; struct gfc_common_head *common; bool lastprivate_conditional; } u; diff --git a/gcc/fortran/module.cc b/gcc/fortran/module.cc index 85aa153bd77..5ddabdcff4d 100644 --- a/gcc/fortran/module.cc +++ b/gcc/fortran/module.cc @@ -4383,10 +4383,10 @@ mio_omp_declare_simd (gfc_namespace *ns, gfc_omp_declare_simd **odsp) } for (n = ods->clauses->lists[OMP_LIST_LINEAR]; n; n = n->next) { - if (n->u.linear_op == OMP_LINEAR_DEFAULT) + if (n->u.linear.op == OMP_LINEAR_DEFAULT) mio_name (4, omp_declare_simd_clauses); else - mio_name (32 + n->u.linear_op, omp_declare_simd_clauses); + mio_name (32 + n->u.linear.op, omp_declare_simd_clauses); mio_symbol_ref (&n->sym); mio_expr (&n->expr); } @@ -4438,7 +4438,7 @@ mio_omp_declare_simd (gfc_namespace *ns, gfc_omp_declare_simd **odsp) case 34: case 35: *ptrs[1] = n = gfc_get_omp_namelist (); -
Re: [Patch] OpenMP/Fortran: Add support for OpenMP 5.2 linear clause syntax
On Mon, Jul 04, 2022 at 04:10:03PM +0200, Tobias Burnus wrote: > This patch adds support for the OpenMP 5.2 syntax for the linear clause, > following the C/C++ patch. The testcases are modified versions from the > C/C++ ones, plus one added one for duplicated modifiers. > > At least to me it is not quite clear when > linear ( var : ref) > refers to a variable 'ref' and when to the linear-modifier 'ref'; the > spec does not seem to be very clear about it. I made an attempt, based See OpenMP 5.2 [59:31-34]: A modifier that is an expression must neither lexically match the name of a simple modifier defined for the clause that is an OpenMP keyword nor modifier-name parenthesized-tokens, where modifier-name is the modifier-name of a complex modifier defined for the clause and parenthesized-tokens is a token sequence that starts with ( and ends with ). So, ref can't be step expression because it lexically matches the name of a simple modifier, so linear (var : ref) is equivalent to old style linear (ref (var):1) while e.g. linear (var : ref + 0) is equivalent to linear (var : step (ref + 0)) > + else if (end_colon) > + { > + gfc_symtree *st; > + bool has_modifiers = false; > + bool duplicate_step = false; > + bool duplicate_mod = false; > + while (true) > + { > + old_loc = gfc_current_locus; > + if (gfc_match ("val )") == MATCH_YES) > + { So, if you see val ) even right after colon (when !old_linear_modifiers), it is always linear modifier, so the if (!has_modifiers) looks wrong. > + if (!has_modifiers) > + { > + gfc_find_sym_tree ("val", NULL, true, &st); > + bool has_val = (st > + && !st->n.sym->attr.function > + && !st->n.sym->attr.dimension); > + locus loc = gfc_current_locus; > + gfc_current_locus = old_loc; > + if (has_val > + && gfc_match (" %e ) ", &step) == MATCH_YES) > + break; > + gfc_current_locus = loc; > + } > + if (linear_op != OMP_LINEAR_DEFAULT) > + { > + duplicate_mod = true; > + break; > + } > + linear_op = OMP_LINEAR_VAL; > + has_modifiers = true; > + break; > + } > + else if (gfc_match ("uval )") == MATCH_YES) > + { Likewise. > + if (!has_modifiers) > + else if (gfc_match ("ref )") == MATCH_YES) > + { And again. > + if (!has_modifiers) > + else if (gfc_match ("step ( ") == MATCH_YES) > + { step ( could start both valid step expression and be a valid modifier. But that decision shouldn't be based on whether there is a step symtree or not, but whether it is step ( whatever ) ) or step ( whatever ) , (in that case it should be parsed as the complex modifier with expression in it), otherwise it is parsed as step expression. The whatever above means some tokens with balanced parentheses. I doubt the Fortran FE has something like that right now. You can certainly try to match "step ( %e ) )" or "step ( %e ) , " first, those would handle the case of valid complex modifier. But, I think if there is interface integer function step (x, y, z) integer :: x, y, z end function step end interface then linear (v : step (x, y, z)) should be rejected, not accepted as valid linear (v : step (step (x, y, z))) I think I should add: int step (int x, int y, int z) { return x + y + z; } int foo (int x) { int i; #pragma omp parallel for linear (x : step (step (1, 2, 3))) for (i = 0; i < 64; i++) x += 6; return x; } int bar (int x) { int i; #pragma omp parallel for linear (x : step (1, 2, 3)) /* { dg-error "expected" } */ for (i = 0; i < 64; i++) x += 6; return x; } as another testcase (where foo used to be invalid before and bar used to be valid). Jakub
Re: [Patch] OpenMP/Fortran: Add support for OpenMP 5.2 linear clause syntax
Hi Jakub, thanks for the comment & spec referral. I have now updated the patch – and included the new C/Fortran testcase. On 04.07.22 16:53, Jakub Jelinek via Fortran wrote: See OpenMP 5.2 [59:31-34]: A modifier that is an expression must neither lexically match the name of a simple modifier defined for the clause that is an OpenMP keyword nor modifier-name parenthesized-tokens, where modifier-name is the modifier-name of a complex modifier defined for the clause and parenthesized-tokens is a token sequence that starts with ( and ends with ). So, ref can't be step expression because it lexically matches the name of a simple modifier, so linear (var : ref) is equivalent to old style linear (ref (var):1) while e.g. linear (var : ref + 0) is equivalent to linear (var : step (ref + 0)) I see. You can certainly try to match "step ( %e ) )" or "step ( %e ) , " first, those would handle the case of valid complex modifier. Done so + plus some more massage in order to support the following, added as C/Fortran testcase: But, I think if there is interface integer function step (x, y, z) integer :: x, y, z end function step end interface then linear (v : step (x, y, z)) should be rejected, not accepted as valid linear (v : step (step (x, y, z))) I think I should add: int step (int x, int y, int z) { return x + y + z; } int foo (int x) { int i; #pragma omp parallel for linear (x : step (step (1, 2, 3))) for (i = 0; i < 64; i++) x += 6; return x; } int bar (int x) { int i; #pragma omp parallel for linear (x : step (1, 2, 3)) /* { dg-error "expected" } */ for (i = 0; i < 64; i++) x += 6; return x; } as another testcase (where foo used to be invalid before and bar used to be valid). Tobias - Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955 OpenMP/Fortran: Add support for OpenMP 5.2 linear clause syntax Fortran part to C/C++ commit r13-1002-g03b71406323ddc065b1d7837d8b43b17e4b048b5 gcc/fortran/ChangeLog: * gfortran.h (gfc_omp_namelist): Update by creating 'linear' struct, move 'linear_op' as 'op' to id and add 'old_modifier' to it. * dump-parse-tree.cc (show_omp_namelist): Update accordingly. * module.cc (mio_omp_declare_simd): Likewise. * trans-openmp.cc (gfc_trans_omp_clauses): Likewise. * openmp.cc (resolve_omp_clauses): Likewise; accept new-style 'val' modifier with do/simd. (gfc_match_omp_clauses): Handle OpenMP 5.2 linear clause syntax. libgomp/ChangeLog: * libgomp.texi (OpenMP 5.2): Mark linear-clause change as 'Y'. gcc/testsuite/ChangeLog: * c-c++-common/gomp/linear-4.c: New test. * gfortran.dg/gomp/linear-2.f90: New test. * gfortran.dg/gomp/linear-3.f90: New test. * gfortran.dg/gomp/linear-4.f90: New test. * gfortran.dg/gomp/linear-5.f90: New test. * gfortran.dg/gomp/linear-6.f90: New test. * gfortran.dg/gomp/linear-7.f90: New test. * gfortran.dg/gomp/linear-8.f90: New test. Co-authored-by: Jakub Jelinek gcc/fortran/dump-parse-tree.cc | 6 +- gcc/fortran/gfortran.h | 6 +- gcc/fortran/module.cc | 6 +- gcc/fortran/openmp.cc | 192 +--- gcc/fortran/trans-openmp.cc | 5 +- gcc/testsuite/c-c++-common/gomp/linear-4.c | 24 gcc/testsuite/gfortran.dg/gomp/linear-2.f90 | 112 gcc/testsuite/gfortran.dg/gomp/linear-3.f90 | 39 ++ gcc/testsuite/gfortran.dg/gomp/linear-4.f90 | 102 +++ gcc/testsuite/gfortran.dg/gomp/linear-5.f90 | 43 +++ gcc/testsuite/gfortran.dg/gomp/linear-6.f90 | 54 gcc/testsuite/gfortran.dg/gomp/linear-7.f90 | 27 gcc/testsuite/gfortran.dg/gomp/linear-8.f90 | 34 + libgomp/libgomp.texi| 2 +- 14 files changed, 622 insertions(+), 30 deletions(-) diff --git a/gcc/fortran/dump-parse-tree.cc b/gcc/fortran/dump-parse-tree.cc index 85c0b98f615..5352008a63d 100644 --- a/gcc/fortran/dump-parse-tree.cc +++ b/gcc/fortran/dump-parse-tree.cc @@ -1421,8 +1421,8 @@ show_omp_namelist (int list_type, gfc_omp_namelist *n) case OMP_MAP_RELEASE: fputs ("release:", dumpfile); break; default: break; } - else if (list_type == OMP_LIST_LINEAR) - switch (n->u.linear_op) + else if (list_type == OMP_LIST_LINEAR && n->u.linear.old_modifier) + switch (n->u.linear.op) { case OMP_LINEAR_REF: fputs ("ref(", dumpfile); break; case OMP_LINEAR_VAL: fputs ("val(", dumpfile); break; @@ -1430,7 +1430,7 @@ show_omp_namelist (int list_type, gfc_omp_namelist *n) default: break; } fprintf (dumpfile, "%s", n->sym ? n->sym->name : "omp_all_memory"); - if (list_type == OMP_LIST_LINEAR && n->u.linear_op != OMP_LINEAR_DEFAULT) + if (list_type == OMP_LIS
Re: [Patch] OpenMP/Fortran: Add support for OpenMP 5.2 linear clause syntax
On Mon, Jul 04, 2022 at 06:09:31PM +0200, Tobias Burnus wrote: > thanks for the comment & spec referral. I have now updated the patch – > and included the new C/Fortran testcase. Thanks. > + while (true) > + { > + old_loc = gfc_current_locus; > + if (gfc_match ("val )") == MATCH_YES) > + { > + if (linear_op != OMP_LINEAR_DEFAULT) > + { > + duplicate_mod = true; > + break; > + } > + linear_op = OMP_LINEAR_VAL; > + has_modifiers = true; > + break; > + } > + else if (gfc_match ("val , ") == MATCH_YES) > + { > + if (linear_op != OMP_LINEAR_DEFAULT) > + { > + duplicate_mod = true; > + break; > + } > + linear_op = OMP_LINEAR_VAL; > + has_modifiers = true; > + continue; > + } Perhaps you could avoid some code duplication by doing it like: bool close_paren = gfc_match ("val )") == MATCH_YES; if (close_paren || gfc_match ("val , ") == MATCH_YES) { if (linear_op != OMP_LINEAR_DEFAULT) { duplicate_mod = true; break; } linear_op = OMP_LINEAR_VAL; has_modifiers = true; if (close_paren) break; else continue; } and similarly for uval and ref. > + else if (!has_modifiers > +&& gfc_match ("%e )", &step) == MATCH_YES) > + { > + if ((step->expr_type == EXPR_FUNCTION > + || step->expr_type == EXPR_VARIABLE) > + && strcmp (step->symtree->name, "step") == 0) > + { > + gfc_current_locus = old_loc; > + gfc_match ("step ("); > + has_error = true; > + } I think the above should accept even linear (v : step (1) + 0) or linear (v : step (1, 2, 3) * 1) which is desirable, because step then will be some other operation (hope folding isn't performed yet). > --- /dev/null > +++ b/gcc/testsuite/gfortran.dg/gomp/linear-4.f90 > @@ -0,0 +1,102 @@ > +! { dg-do compile } > +! { dg-options "-fopenmp" } > + > +module m > +implicit none > + > +integer :: i > + > +interface > + integer function bar (x, y, z) > +integer :: x, y > +integer, value :: z > +!!$omp declare simd linear (x : ref, step (1)) linear (y : step (2), > uval) Are all these !! intentional? The test then doesn't test much. Or is that a FIXME? Jakub
Re: [Patch] OpenMP/Fortran: Add support for OpenMP 5.2 linear clause syntax
On 04.07.22 19:20, Jakub Jelinek wrote: Perhaps you could avoid some code duplication by doing it like: bool close_paren = gfc_match ("val )") == MATCH_YES; if (close_paren || gfc_match ("val , ") == MATCH_YES) Done! Good idea! I was thinking of things like ...peek_char() but that takes the next char and not the last one; but your method works. + else if (!has_modifiers + && gfc_match ("%e )", &step) == MATCH_YES) +{ + if ((step->expr_type == EXPR_FUNCTION +|| step->expr_type == EXPR_VARIABLE) + && strcmp (step->symtree->name, "step") == 0) +{ + gfc_current_locus = old_loc; + gfc_match ("step ("); + has_error = true; +} I think the above should accept even linear (v : step (1) + 0) or linear (v : step (1, 2, 3) * 1) which is desirable, because step then will be some other operation (hope folding isn't performed yet). Well, it does. In that case expr_type == EXPR_OP. I added the latter to the C/C++ and the Fortran testcase. +!!$omp declare simd linear (x : ref, step (1)) linear (y : step (2), uval) Are all these !! intentional? No – just a missed undo after debugging. It worked/works after changing it back to '!'. Revised version attached. Tobias - Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955 OpenMP/Fortran: Add support for OpenMP 5.2 linear clause syntax Fortran part to C/C++ commit r13-1002-g03b71406323ddc065b1d7837d8b43b17e4b048b5 gcc/fortran/ChangeLog: * gfortran.h (gfc_omp_namelist): Update by creating 'linear' struct, move 'linear_op' as 'op' to id and add 'old_modifier' to it. * dump-parse-tree.cc (show_omp_namelist): Update accordingly. * module.cc (mio_omp_declare_simd): Likewise. * trans-openmp.cc (gfc_trans_omp_clauses): Likewise. * openmp.cc (resolve_omp_clauses): Likewise; accept new-style 'val' modifier with do/simd. (gfc_match_omp_clauses): Handle OpenMP 5.2 linear clause syntax. libgomp/ChangeLog: * libgomp.texi (OpenMP 5.2): Mark linear-clause change as 'Y'. gcc/testsuite/ChangeLog: * c-c++-common/gomp/linear-4.c: New test. * gfortran.dg/gomp/linear-2.f90: New test. * gfortran.dg/gomp/linear-3.f90: New test. * gfortran.dg/gomp/linear-4.f90: New test. * gfortran.dg/gomp/linear-5.f90: New test. * gfortran.dg/gomp/linear-6.f90: New test. * gfortran.dg/gomp/linear-7.f90: New test. * gfortran.dg/gomp/linear-8.f90: New test. Co-authored-by: Jakub Jelinek gcc/fortran/dump-parse-tree.cc | 6 +- gcc/fortran/gfortran.h | 6 +- gcc/fortran/module.cc | 6 +- gcc/fortran/openmp.cc | 163 gcc/fortran/trans-openmp.cc | 5 +- gcc/testsuite/c-c++-common/gomp/linear-4.c | 34 ++ gcc/testsuite/gfortran.dg/gomp/linear-2.f90 | 112 +++ gcc/testsuite/gfortran.dg/gomp/linear-3.f90 | 39 +++ gcc/testsuite/gfortran.dg/gomp/linear-4.f90 | 102 + gcc/testsuite/gfortran.dg/gomp/linear-5.f90 | 43 gcc/testsuite/gfortran.dg/gomp/linear-6.f90 | 54 + gcc/testsuite/gfortran.dg/gomp/linear-7.f90 | 27 + gcc/testsuite/gfortran.dg/gomp/linear-8.f90 | 44 libgomp/libgomp.texi| 2 +- 14 files changed, 613 insertions(+), 30 deletions(-) diff --git a/gcc/fortran/dump-parse-tree.cc b/gcc/fortran/dump-parse-tree.cc index 85c0b98f615..5352008a63d 100644 --- a/gcc/fortran/dump-parse-tree.cc +++ b/gcc/fortran/dump-parse-tree.cc @@ -1421,8 +1421,8 @@ show_omp_namelist (int list_type, gfc_omp_namelist *n) case OMP_MAP_RELEASE: fputs ("release:", dumpfile); break; default: break; } - else if (list_type == OMP_LIST_LINEAR) - switch (n->u.linear_op) + else if (list_type == OMP_LIST_LINEAR && n->u.linear.old_modifier) + switch (n->u.linear.op) { case OMP_LINEAR_REF: fputs ("ref(", dumpfile); break; case OMP_LINEAR_VAL: fputs ("val(", dumpfile); break; @@ -1430,7 +1430,7 @@ show_omp_namelist (int list_type, gfc_omp_namelist *n) default: break; } fprintf (dumpfile, "%s", n->sym ? n->sym->name : "omp_all_memory"); - if (list_type == OMP_LIST_LINEAR && n->u.linear_op != OMP_LINEAR_DEFAULT) + if (list_type == OMP_LIST_LINEAR && n->u.linear.op != OMP_LINEAR_DEFAULT) fputc (')', dumpfile); if (n->expr) { diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 463d9692236..696aadd7db6 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1345,7 +1345,11 @@ typedef struct
Re: [Patch] OpenMP/Fortran: Add support for OpenMP 5.2 linear clause syntax
On Mon, Jul 04, 2022 at 08:29:37PM +0200, Tobias Burnus wrote: > Fortran part to C/C++ > commit r13-1002-g03b71406323ddc065b1d7837d8b43b17e4b048b5 > > gcc/fortran/ChangeLog: > > * gfortran.h (gfc_omp_namelist): Update by creating 'linear' struct, > move 'linear_op' as 'op' to id and add 'old_modifier' to it. > * dump-parse-tree.cc (show_omp_namelist): Update accordingly. > * module.cc (mio_omp_declare_simd): Likewise. > * trans-openmp.cc (gfc_trans_omp_clauses): Likewise. > * openmp.cc (resolve_omp_clauses): Likewise; accept new-style > 'val' modifier with do/simd. > (gfc_match_omp_clauses): Handle OpenMP 5.2 linear clause syntax. > > libgomp/ChangeLog: > > * libgomp.texi (OpenMP 5.2): Mark linear-clause change as 'Y'. > > gcc/testsuite/ChangeLog: > > * c-c++-common/gomp/linear-4.c: New test. > * gfortran.dg/gomp/linear-2.f90: New test. > * gfortran.dg/gomp/linear-3.f90: New test. > * gfortran.dg/gomp/linear-4.f90: New test. > * gfortran.dg/gomp/linear-5.f90: New test. > * gfortran.dg/gomp/linear-6.f90: New test. > * gfortran.dg/gomp/linear-7.f90: New test. > * gfortran.dg/gomp/linear-8.f90: New test. Ok, thanks. Jakub