From 091b6dbc48177fa3ef15d62ea280ef6cb61c05b2 Mon Sep 17 00:00:00 2001 From: Tobias Burnus Date: Mon, 28 Nov 2022 11:08:32 +0100 Subject: OpenMP/Fortran: Permit end-clause on directive gcc/fortran/ChangeLog: * openmp.cc (OMP_DO_CLAUSES, OMP_SCOPE_CLAUSES, OMP_SECTIONS_CLAUSES): Add 'nowait'. (OMP_SINGLE_CLAUSES): Add 'nowait' and 'copyprivate'. (gfc_match_omp_distribute_parallel_do, gfc_match_omp_distribute_parallel_do_simd, gfc_match_omp_parallel_do, gfc_match_omp_parallel_do_simd, gfc_match_omp_parallel_sections, gfc_match_omp_teams_distribute_parallel_do, gfc_match_omp_teams_distribute_parallel_do_simd): Disallow 'nowait'. (gfc_match_omp_workshare): Match 'nowait' clause. (gfc_match_omp_end_single): Use clause matcher for 'nowait'. (resolve_omp_clauses): Reject 'nowait' + 'copyprivate'. * parse.cc (decode_omp_directive): Break too long line. (parse_omp_do, parse_omp_structured_block): Diagnose duplicated 'nowait' clause. libgomp/ChangeLog: * libgomp.texi (OpenMP 5.2): Mark end-directive as Y. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/copyprivate-1.f90: New test. * gfortran.dg/gomp/copyprivate-2.f90: New test. * gfortran.dg/gomp/nowait-2.f90: Move dg-error tests ... * gfortran.dg/gomp/nowait-4.f90: ... to this new file. * gfortran.dg/gomp/nowait-5.f90: New test. * gfortran.dg/gomp/nowait-6.f90: New test. * gfortran.dg/gomp/nowait-7.f90: New test. * gfortran.dg/gomp/nowait-8.f90: New test. --- gcc/fortran/openmp.cc | 57 ++++++++++++++++++++++++--------------------------- gcc/fortran/parse.cc | 33 +++++++++++++++++++++++++---- 2 files changed, 56 insertions(+), 34 deletions(-) (limited to 'gcc/fortran') diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc index e0e3b52..862c649 100644 --- a/gcc/fortran/openmp.cc +++ b/gcc/fortran/openmp.cc @@ -4173,17 +4173,19 @@ cleanup: (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \ | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION \ | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED | OMP_CLAUSE_COLLAPSE \ - | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER | OMP_CLAUSE_ALLOCATE) + | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ORDER | OMP_CLAUSE_ALLOCATE \ + | OMP_CLAUSE_NOWAIT) #define OMP_LOOP_CLAUSES \ (omp_mask (OMP_CLAUSE_BIND) | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_ORDER \ | OMP_CLAUSE_PRIVATE | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION) #define OMP_SCOPE_CLAUSES \ (omp_mask (OMP_CLAUSE_PRIVATE) |OMP_CLAUSE_FIRSTPRIVATE \ - | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE) + | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT) #define OMP_SECTIONS_CLAUSES \ (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \ - | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_ALLOCATE) + | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION \ + | OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT) #define OMP_SIMD_CLAUSES \ (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE \ | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN \ @@ -4233,7 +4235,7 @@ cleanup: | OMP_CLAUSE_ORDER | OMP_CLAUSE_ALLOCATE) #define OMP_SINGLE_CLAUSES \ (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE \ - | OMP_CLAUSE_ALLOCATE) + | OMP_CLAUSE_ALLOCATE | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_COPYPRIVATE) #define OMP_ORDERED_CLAUSES \ (omp_mask (OMP_CLAUSE_THREADS) | OMP_CLAUSE_SIMD) #define OMP_DECLARE_TARGET_CLAUSES \ @@ -4247,7 +4249,8 @@ cleanup: (omp_mask (OMP_CLAUSE_FILTER)) #define OMP_ERROR_CLAUSES \ (omp_mask (OMP_CLAUSE_AT) | OMP_CLAUSE_MESSAGE | OMP_CLAUSE_SEVERITY) - +#define OMP_WORKSHARE_CLAUSES \ + omp_mask (OMP_CLAUSE_NOWAIT) static match @@ -4458,8 +4461,8 @@ gfc_match_omp_distribute_parallel_do (void) return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO, (OMP_DISTRIBUTE_CLAUSES | OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES) - & ~(omp_mask (OMP_CLAUSE_ORDERED)) - & ~(omp_mask (OMP_CLAUSE_LINEAR))); + & ~(omp_mask (OMP_CLAUSE_ORDERED) + | OMP_CLAUSE_LINEAR | OMP_CLAUSE_NOWAIT)); } @@ -4469,7 +4472,7 @@ gfc_match_omp_distribute_parallel_do_simd (void) return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD, (OMP_DISTRIBUTE_CLAUSES | OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES | OMP_SIMD_CLAUSES) - & ~(omp_mask (OMP_CLAUSE_ORDERED))); + & ~(omp_mask (OMP_CLAUSE_ORDERED) | OMP_CLAUSE_NOWAIT)); } @@ -5770,7 +5773,8 @@ match gfc_match_omp_parallel_do (void) { return match_omp (EXEC_OMP_PARALLEL_DO, - OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES); + (OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES) + & ~(omp_mask (OMP_CLAUSE_NOWAIT))); } @@ -5778,7 +5782,8 @@ match gfc_match_omp_parallel_do_simd (void) { return match_omp (EXEC_OMP_PARALLEL_DO_SIMD, - OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES | OMP_SIMD_CLAUSES); + (OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES | OMP_SIMD_CLAUSES) + & ~(omp_mask (OMP_CLAUSE_NOWAIT))); } @@ -5834,7 +5839,8 @@ match gfc_match_omp_parallel_sections (void) { return match_omp (EXEC_OMP_PARALLEL_SECTIONS, - OMP_PARALLEL_CLAUSES | OMP_SECTIONS_CLAUSES); + (OMP_PARALLEL_CLAUSES | OMP_SECTIONS_CLAUSES) + & ~(omp_mask (OMP_CLAUSE_NOWAIT))); } @@ -6320,8 +6326,8 @@ gfc_match_omp_teams_distribute_parallel_do (void) return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO, (OMP_TEAMS_CLAUSES | OMP_DISTRIBUTE_CLAUSES | OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES) - & ~(omp_mask (OMP_CLAUSE_ORDERED)) - & ~(omp_mask (OMP_CLAUSE_LINEAR))); + & ~(omp_mask (OMP_CLAUSE_ORDERED) + | OMP_CLAUSE_LINEAR | OMP_CLAUSE_NOWAIT)); } @@ -6331,7 +6337,8 @@ gfc_match_omp_teams_distribute_parallel_do_simd (void) return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD, (OMP_TEAMS_CLAUSES | OMP_DISTRIBUTE_CLAUSES | OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES - | OMP_SIMD_CLAUSES) & ~(omp_mask (OMP_CLAUSE_ORDERED))); + | OMP_SIMD_CLAUSES) + & ~(omp_mask (OMP_CLAUSE_ORDERED) | OMP_CLAUSE_NOWAIT)); } @@ -6347,14 +6354,7 @@ gfc_match_omp_teams_distribute_simd (void) match gfc_match_omp_workshare (void) { - if (gfc_match_omp_eos () != MATCH_YES) - { - gfc_error ("Unexpected junk after $OMP WORKSHARE statement at %C"); - return MATCH_ERROR; - } - new_st.op = EXEC_OMP_WORKSHARE; - new_st.ext.omp_clauses = gfc_get_omp_clauses (); - return MATCH_YES; + return match_omp (EXEC_OMP_WORKSHARE, OMP_WORKSHARE_CLAUSES); } @@ -6658,14 +6658,8 @@ match gfc_match_omp_end_single (void) { gfc_omp_clauses *c; - if (gfc_match ("% nowait") == MATCH_YES) - { - new_st.op = EXEC_OMP_END_NOWAIT; - new_st.ext.omp_bool = true; - return MATCH_YES; - } - if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_COPYPRIVATE)) - != MATCH_YES) + if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_COPYPRIVATE) + | OMP_CLAUSE_NOWAIT) != MATCH_YES) return MATCH_ERROR; new_st.op = EXEC_OMP_END_SINGLE; new_st.ext.omp_clauses = c; @@ -7406,6 +7400,9 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, } break; case OMP_LIST_COPYPRIVATE: + if (omp_clauses->nowait) + gfc_error ("NOWAIT clause must not be used with COPYPRIVATE " + "clause at %L", &n->where); for (; n != NULL; n = n->next) { if (n->sym->as && n->sym->as->type == AS_ASSUMED_SIZE) diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc index f04fd13..51ff0fc 100644 --- a/gcc/fortran/parse.cc +++ b/gcc/fortran/parse.cc @@ -942,7 +942,8 @@ decode_omp_directive (void) matchs ("end ordered", gfc_match_omp_eos_error, ST_OMP_END_ORDERED); matchs ("end parallel do simd", gfc_match_omp_eos_error, ST_OMP_END_PARALLEL_DO_SIMD); - matcho ("end parallel do", gfc_match_omp_eos_error, ST_OMP_END_PARALLEL_DO); + matcho ("end parallel do", gfc_match_omp_eos_error, + ST_OMP_END_PARALLEL_DO); matcho ("end parallel loop", gfc_match_omp_eos_error, ST_OMP_END_PARALLEL_LOOP); matcho ("end parallel masked taskloop simd", gfc_match_omp_eos_error, @@ -5305,7 +5306,13 @@ parse_omp_do (gfc_statement omp_st) if (st == omp_end_st) { if (new_st.op == EXEC_OMP_END_NOWAIT) - cp->ext.omp_clauses->nowait |= new_st.ext.omp_bool; + { + if (cp->ext.omp_clauses->nowait && new_st.ext.omp_bool) + gfc_error_now ("Duplicated NOWAIT clause on %s and %s at %C", + gfc_ascii_statement (omp_st), + gfc_ascii_statement (omp_end_st)); + cp->ext.omp_clauses->nowait |= new_st.ext.omp_bool; + } else gcc_assert (new_st.op == EXEC_NOP); gfc_clear_new_st (); @@ -5745,6 +5752,10 @@ parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only) switch (new_st.op) { case EXEC_OMP_END_NOWAIT: + if (cp->ext.omp_clauses->nowait && new_st.ext.omp_bool) + gfc_error_now ("Duplicated NOWAIT clause on %s and %s at %C", + gfc_ascii_statement (omp_st), + gfc_ascii_statement (omp_end_st)); cp->ext.omp_clauses->nowait |= new_st.ext.omp_bool; break; case EXEC_OMP_END_CRITICAL: @@ -5759,8 +5770,22 @@ parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only) new_st.ext.omp_name = NULL; break; case EXEC_OMP_END_SINGLE: - cp->ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE] - = new_st.ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE]; + if (cp->ext.omp_clauses->nowait && new_st.ext.omp_clauses->nowait) + gfc_error_now ("Duplicated NOWAIT clause on %s and %s at %C", + gfc_ascii_statement (omp_st), + gfc_ascii_statement (omp_end_st)); + cp->ext.omp_clauses->nowait |= new_st.ext.omp_clauses->nowait; + if (cp->ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE]) + { + gfc_omp_namelist *nl; + for (nl = cp->ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE]; + nl->next; nl = nl->next); + ; + nl->next = new_st.ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE]; + } + else + cp->ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE] + = new_st.ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE]; new_st.ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE] = NULL; gfc_free_omp_clauses (new_st.ext.omp_clauses); break; -- cgit v1.1