[Patch] Fortran: Fixes to OpenMP 'interop' directive parsing support
This patch fixes a couple of issues, like a missing white-space gobbling after matching an expression. It also reorganizes some code to handle 'identifier_"string"' vs. 'identifier' better as there were some diagnostic issues. (OpenMP requires for 'fr' that the argument is either an identifier (that is a scalar integer parameter) or a string; while for the older syntax, it can be any constant integer expression.) However, the two main changes are: * 'fr' and 'attr' actually support a list of arguments. While I believe 'attr("x", "y") and "attr("x"),attr("y")' are semantically identically, supporting more than one (or zero) values for 'fr' required a different encoding. * Jakub additionally suggested that for 'fr', which supports constant integers and string literals, we could pass on integer values – and do some checking. That's what this patch does: Known string values are converted to their associated integer values, others to 0. And if the integer/string value is unknown, a warning is printed [-Wopenmp]. Known values are those in the "OpenMP API Additional Definitions" document, https://www.openmp.org/specifications/ – with the addition of hsa / 7, which has been voted at spec level (no idea about ARB level) but not yet published. Note that that's the warning is based on what is defined there, i.e. 'level_zero' there is no warning, even though GCC does not support it. Obviously, if will add another value next year, GCC 15 will not support it and warn, even if the code is perfectly valid. — But I guess we can live with a warning in that case. Comments, remarks, suggestions? — Especially regarding the internal representation? Tobias PS: Next step will be to get the C/C++ parsing working, which also implies encoding this representation into 'tree'. (Then doing the tree conversion for Fortran.) Once satisfied with that, the middle end + libgomp part that links those bits will come next. And the question whether there should be one call per 'interop' directive or might be multiple (e.g. one per interop object in 'init'/'use'/'destroy'). Fortran: Fixes to OpenMP 'interop' directive parsing support Handle lists as argument to 'fr' and 'attr'; fix parsing corner cases. Additionally, 'fr' values are now internally stored as integer, permitting the diagnoses (warning) for values not defined in the OpenMP additional definitions document. PR fortran/116661 gcc/fortran/ChangeLog: * gfortran.h (gfc_omp_namelist): Rename 'init' members for clarity. * match.cc (gfc_free_omp_namelist): Handle renaming. * dump-parse-tree.cc (show_omp_namelist): Update for new format and features. * openmp.cc (gfc_match_omp_prefer_type): Parse list to 'fr' and 'attr'; store 'fr' values as integer. (gfc_match_omp_init): Rename variable names. gcc/ChangeLog: * omp-api.h (omp_get_fr_id_from_name, omp_get_name_from_fr_id): New prototypes. * omp-general.cc (omp_get_fr_id_from_name, omp_get_name_from_fr_id): New. include/ChangeLog: * gomp-constants.h (GOMP_INTEROP_IFR_LAST, GOMP_INTEROP_IFR_SEPARATOR, GOMP_INTEROP_IFR_NONE): New. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/interop-1.f90: Extend, update dg-*. * gfortran.dg/gomp/interop-2.f90: Update dg-error. * gfortran.dg/gomp/interop-3.f90: Add dg-warning. gcc/fortran/dump-parse-tree.cc | 84 +--- gcc/fortran/gfortran.h | 4 +- gcc/fortran/match.cc | 10 +- gcc/fortran/openmp.cc| 305 --- gcc/omp-api.h| 3 + gcc/omp-general.cc | 29 +++ gcc/testsuite/gfortran.dg/gomp/interop-1.f90 | 32 ++- gcc/testsuite/gfortran.dg/gomp/interop-2.f90 | 2 +- gcc/testsuite/gfortran.dg/gomp/interop-3.f90 | 2 +- include/gomp-constants.h | 5 + 10 files changed, 314 insertions(+), 162 deletions(-) diff --git a/gcc/fortran/dump-parse-tree.cc b/gcc/fortran/dump-parse-tree.cc index 8fc6141611c..3547d7f8aca 100644 --- a/gcc/fortran/dump-parse-tree.cc +++ b/gcc/fortran/dump-parse-tree.cc @@ -37,6 +37,8 @@ along with GCC; see the file COPYING3. If not see #include "constructor.h" #include "version.h" #include "parse.h" /* For gfc_ascii_statement. */ +#include "omp-api.h" /* For omp_get_name_from_fr_id. */ +#include "gomp-constants.h" /* For GOMP_INTEROP_IFR_SEPARATOR. */ /* Keep track of indentation for symbol tree dumps. */ static int show_level = 0; @@ -1537,35 +1539,69 @@ show_omp_namelist (int list_type, gfc_omp_namelist *n) } else if (list_type == OMP_LIST_INIT) { - int i = 0; if (n->u.init.target) fputs ("target,", dumpfile); if (n->u.init.targetsync) fputs ("targetsync,", dumpfile); - char *prefer_type = n->u.init.str; - if (n->u.init.len) - fputs ("prefer_type(", dumpfile); - if (n->u.init.len) - while (*prefer_type) - { - fputc ('{', dumpfile); - if (n->u2.interop_int
[patch, fortran, committed] module support for UNSIGNED
Hello world, I just pushed Steve's patch for module support to trunk as obvious, as https://gcc.gnu.org/g:2847a541c1f19b67ae84be8d0f6dc8e1f9371d16 . Best regards Thomas gcc/fortran/ChangeLog: * module.cc (bt_types): Add BT_UNSIGNED. gcc/testsuite/ChangeLog: * gfortran.dg/unsigned_kiss.f90: New test. diff --git a/gcc/fortran/module.cc b/gcc/fortran/module.cc index c565b84d61b..8cf58ff5142 100644 --- a/gcc/fortran/module.cc +++ b/gcc/fortran/module.cc @@ -2781,6 +2781,7 @@ static const mstring bt_types[] = { minit ("UNKNOWN", BT_UNKNOWN), minit ("VOID", BT_VOID), minit ("ASSUMED", BT_ASSUMED), +minit ("UNSIGNED", BT_UNSIGNED), minit (NULL, -1) }; diff --git a/gcc/testsuite/gfortran.dg/unsigned_kiss.f90 b/gcc/testsuite/gfortran.dg/unsigned_kiss.f90 new file mode 100644 index 000..46ee86ccd26 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/unsigned_kiss.f90 @@ -0,0 +1,100 @@ +! +! { dg-do run } +! { dg-options "-funsigned" } +! +! Modern Fortran rewrite of Marsaglia's 64-bit KISS PRNG. +! https://www.thecodingforums.com/threads/64-bit-kiss-rngs.673657/ +! +module kissm + + implicit none + private + public uk, kseed, kiss + + integer, parameter :: uk = kind(1u_8) ! Check kind() works. + + ! Default seeds. Checks unsigned with parameter attribute. + unsigned(uk), parameter :: seed(4) = [ & + & 1234567890987654321u_uk, 362436362436362436u_uk, & + & 1066149217761810u_uk, 123456123456123456u_uk ] + + ! Seeds used during generation + unsigned(uk), save :: sd(4) = seed + + contains + + ! Tests unsigned in an internal function. + function s(x) + unsigned(uk) s + unsigned(uk), intent(in) :: x + s = ishft(x, -63)! Tests ishft + end function + + ! Poor seeding routine. Need to check v for entropy! + ! Tests intent(in) and optional attributes. + ! Tests ishftc() and array constructors. + subroutine kseed(v) + unsigned(uk), intent(in), optional :: v + if (present(v)) then +sd = seed + [ishftc(v,1), ishftc(v,15), ishftc(v,31), ishftc(v,44)] + else +sd = seed + end if + end subroutine kseed + + function kiss() + unsigned(uk) kiss + unsigned(uk) m, t + integer k + + ! Test unsigned in a statement function + m(t, k) = ieor(t, ishft(t, k)) + + t = ishft(sd(1), 58) + sd(4) + if (s(sd(1)) == s(t)) then +sd(4) = ishft(sd(1), -6) + s(sd(1)) + else +sd(4) = ishft(sd(1), -6) + 1u_uk - s(sd(1) + t) + endif + + sd(1) = t + sd(1) + sd(2) = m(m(m(sd(2), 13), -17), 43) + sd(3) = 6906969069u_uk * sd(3) + 1234567u_uk + kiss = sd(1) + sd(2) + sd(3) + end function kiss + +end module kissm + +program testkiss + use kissm + integer, parameter :: n = 4 + unsigned(uk) prn(4) + + ! Default sequence + unsigned(uk), parameter :: a(4) = [8932985056925012148u_uk, & + & 5710300428094272059u_uk, 18342510866933518593u_uk, & + & 14303636270573868250u_uk] + + ! Sequence with the seed 123412341234u_uk + unsigned(uk), parameter :: b(4) = [4002508872477953753u_uk, & + & 18025327658415290923u_uk, 16058856976144281263u_uk, & + & 11842224026193909403u_uk] + + do i = 1, n + prn(i) = kiss() + end do + if (any(prn /= a)) stop 1 + + call kseed(123412341234u_uk) + do i = 1, n + prn(i) = kiss() + end do + if (any(prn /= b)) stop 2 + + call kseed() + do i = 1, n + prn(i) = kiss() + end do + if (any(prn /= a)) stop 3 + +end program testkiss
[patch, teststuite, Fortran, committed] Fix endianness issue on test case
I just committed the fix for PR 116653 as obvious. Unfortunately, I left out the description in the ChangeLog, I hope it is clear enough. Best regards Thomas https://gcc.gnu.org/g:5d9486c29938d79beb798dce1a5509da54fe8c9f commit r15-3619-g5d9486c29938d79beb798dce1a5509da54fe8c9f Author: Thomas Koenig Date: Fri Sep 13 07:47:24 2024 +0200 Fix endianness issue on unsigned_21.f90. gcc/testsuite/ChangeLog: PR fortran/116653 * gfortran.dg/unsigned_21.f90: * gfortran.dg/unsigned_21_be.f90: New test. diff --git a/gcc/testsuite/gfortran.dg/unsigned_21.f90 b/gcc/testsuite/gfortran.dg/unsigned_21.f90 index 23302c7eabe..c3f65a469dc 100644 --- a/gcc/testsuite/gfortran.dg/unsigned_21.f90 +++ b/gcc/testsuite/gfortran.dg/unsigned_21.f90 @@ -1,5 +1,6 @@ ! { dg-do run } ! { dg-options "-funsigned" } +! { dg-require-effective-target le } program main integer :: i integer(2) :: j diff --git a/gcc/testsuite/gfortran.dg/unsigned_21_be.f90 b/gcc/testsuite/gfortran.dg/unsigned_21_be.f90 new file mode 100644 index 000..64fecd9cd4a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/unsigned_21_be.f90 @@ -0,0 +1,14 @@ +! { dg-do run } +! { dg-options "-funsigned" } +! { dg-require-effective-target be } +program main + integer :: i + integer(2) :: j + unsigned :: u + i = -1 + u = transfer(i,u) + if (u /= huge(u)) error stop 1 + u = 4278058235u + j = transfer(u,j) + if (j /= -259) error stop 2 +end program main