diff options
author | Tobias Burnus <tobias@codesourcery.com> | 2020-07-29 10:37:44 +0200 |
---|---|---|
committer | Tobias Burnus <tobias@codesourcery.com> | 2020-07-29 10:37:44 +0200 |
commit | 269322ece17202632bc354e9c510e4a5bd6ad84b (patch) | |
tree | 0f455436d3c7c8d20fa70bb68296c9e9445fb3b1 /gcc/fortran/parse.c | |
parent | 5c180464b7b0827b3cc07a78e96dfe55352db33f (diff) | |
download | gcc-269322ece17202632bc354e9c510e4a5bd6ad84b.zip gcc-269322ece17202632bc354e9c510e4a5bd6ad84b.tar.gz gcc-269322ece17202632bc354e9c510e4a5bd6ad84b.tar.bz2 |
OpenMP: Add 'omp requires' to Fortran (mostly parsing)
gcc/fortran/ChangeLog:
* gfortran.h (enum gfc_statement): Add ST_OMP_REQUIRES.
(enum gfc_omp_requires_kind): New.
(enum gfc_omp_atomic_op): Add GFC_OMP_ATOMIC_ACQ_REL.
(struct gfc_namespace): Add omp_requires and omp_target_seen.
(gfc_omp_requires_add_clause,
(gfc_check_omp_requires): New.
* match.h (gfc_match_omp_requires): New.
* module.c (enum ab_attribute, attr_bits): Add omp requires clauses.
(mio_symbol_attribute): Read/write them.
* openmp.c (gfc_check_omp_requires, (gfc_omp_requires_add_clause,
gfc_match_omp_requires): New.
(gfc_match_omp_oacc_atomic): Use requires's default mem-order.
* parse.c (decode_omp_directive): Match requires, set omp_target_seen.
(gfc_ascii_statement): Handle ST_OMP_REQUIRES.
* trans-openmp.c (gfc_trans_omp_atomic): Handle GFC_OMP_ATOMIC_ACQ_REL.
gcc/testsuite/ChangeLog:
* gfortran.dg/gomp/requires-1.f90: New test.
* gfortran.dg/gomp/requires-2.f90: New test.
* gfortran.dg/gomp/requires-3.f90: New test.
* gfortran.dg/gomp/requires-4.f90: New test.
* gfortran.dg/gomp/requires-5.f90: New test.
* gfortran.dg/gomp/requires-6.f90: New test.
* gfortran.dg/gomp/requires-7.f90: New test.
* gfortran.dg/gomp/requires-8.f90: New test.
* gfortran.dg/gomp/requires-9.f90: New test.
Diffstat (limited to 'gcc/fortran/parse.c')
-rw-r--r-- | gcc/fortran/parse.c | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c index 96fd4aa..6669621 100644 --- a/gcc/fortran/parse.c +++ b/gcc/fortran/parse.c @@ -995,6 +995,9 @@ decode_omp_directive (void) ST_OMP_PARALLEL_WORKSHARE); matcho ("parallel", gfc_match_omp_parallel, ST_OMP_PARALLEL); break; + case 'r': + matcho ("requires", gfc_match_omp_requires, ST_OMP_REQUIRES); + break; case 's': matcho ("sections", gfc_match_omp_sections, ST_OMP_SECTIONS); matcho ("section", gfc_match_omp_eos_error, ST_OMP_SECTION); @@ -1086,6 +1089,38 @@ decode_omp_directive (void) return ST_NONE; } } + switch (ret) + { + case ST_OMP_DECLARE_TARGET: + case ST_OMP_TARGET: + case ST_OMP_TARGET_DATA: + case ST_OMP_TARGET_ENTER_DATA: + case ST_OMP_TARGET_EXIT_DATA: + case ST_OMP_TARGET_TEAMS: + case ST_OMP_TARGET_TEAMS_DISTRIBUTE: + case ST_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD: + case ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO: + case ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD: + case ST_OMP_TARGET_PARALLEL: + case ST_OMP_TARGET_PARALLEL_DO: + case ST_OMP_TARGET_PARALLEL_DO_SIMD: + case ST_OMP_TARGET_SIMD: + case ST_OMP_TARGET_UPDATE: + { + gfc_namespace *prog_unit = gfc_current_ns; + while (prog_unit->parent) + { + if (gfc_state_stack->previous + && gfc_state_stack->previous->state == COMP_INTERFACE) + break; + prog_unit = prog_unit->parent; + } + prog_unit->omp_target_seen = true; + break; + } + default: + break; + } return ret; do_spec_only: @@ -1604,7 +1639,8 @@ next_statement (void) /* OpenMP declaration statements. */ #define case_omp_decl case ST_OMP_THREADPRIVATE: case ST_OMP_DECLARE_SIMD: \ - case ST_OMP_DECLARE_TARGET: case ST_OMP_DECLARE_REDUCTION + case ST_OMP_DECLARE_TARGET: case ST_OMP_DECLARE_REDUCTION: \ + case ST_OMP_REQUIRES /* Block end statements. Errors associated with interchanging these are detected in gfc_match_end(). */ @@ -2407,6 +2443,9 @@ gfc_ascii_statement (gfc_statement st) case ST_OMP_PARALLEL_WORKSHARE: p = "!$OMP PARALLEL WORKSHARE"; break; + case ST_OMP_REQUIRES: + p = "!$OMP REQUIRES"; + break; case ST_OMP_SECTIONS: p = "!$OMP SECTIONS"; break; @@ -6516,10 +6555,18 @@ done: } while (changed); - /* Fixup for external procedures. */ + /* Fixup for external procedures and resolve 'omp requires'. */ + int omp_requires; + omp_requires = 0; + for (gfc_current_ns = gfc_global_ns_list; gfc_current_ns; + gfc_current_ns = gfc_current_ns->sibling) + { + omp_requires |= gfc_current_ns->omp_requires; + gfc_check_externals (gfc_current_ns); + } for (gfc_current_ns = gfc_global_ns_list; gfc_current_ns; gfc_current_ns = gfc_current_ns->sibling) - gfc_check_externals (gfc_current_ns); + gfc_check_omp_requires (gfc_current_ns, omp_requires); /* Do the parse tree dump. */ gfc_current_ns = flag_dump_fortran_original ? gfc_global_ns_list : NULL; |