Re: [Patch] OpenMP/Fortran: Reject not strictly nested target -> teams [PR110725, PR71065]
Now committed as r14-2754-g2e31fe431b08b0 with a minor addition: On 24.07.23 22:05, Tobias Burnus wrote: The current patch rejects nested blocks, be it 'omp target; block; block; omp teams;' which was before in the testcase. But now also or be it 'omp target; block; block;end block; omp teams'. is tested for. Somehow, the second dg-error line in an modified testcase did not make it in the first commit; now fixed in r14-2759-g50656980497d77 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 commit 50656980497d77ac12a5e7179013a6af09ba32f7 Author: Tobias Burnus Date: Tue Jul 25 09:28:43 2023 +0200 gfortran.dg/gomp/pr99226.f90: Add missing dg-error Follow up to r14-2754-g2e31fe431b08b0302e1fa8a1c18ee51adafd41df which added a check that a target region with teams does not have anything anything else strictly nested in the target. When changing the dg-error for this PR, somehow the addition of a dg-error in a second line was lost (the message uses (1) and (2) as location, showing two lines, both need a dg-error with the same message). gcc/testsuite/ChangeLog: * gfortran.dg/gomp/pr99226.f90: Update dg-error. --- gcc/testsuite/gfortran.dg/gomp/pr99226.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/testsuite/gfortran.dg/gomp/pr99226.f90 b/gcc/testsuite/gfortran.dg/gomp/pr99226.f90 index 2aea0c15585..d1b35076dd0 100644 --- a/gcc/testsuite/gfortran.dg/gomp/pr99226.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/pr99226.f90 @@ -3,7 +3,7 @@ subroutine sub (n) integer :: n, i !$omp target ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } - !$omp teams distribute dist_schedule (static,n+4) + !$omp teams distribute dist_schedule (static,n+4) ! { dg-error "OMP TARGET region at .1. with a nested TEAMS at .2. may not contain any other statement, declaration or directive outside of the single TEAMS construct" } do i = 1, 8 end do !$omp teams distribute dist_schedule (static,n+4) commit 2e31fe431b08b0302e1fa8a1c18ee51adafd41df Author: Tobias Burnus Date: Mon Jul 24 22:57:07 2023 +0200 OpenMP/Fortran: Reject not strictly nested target -> teams [PR110725, PR71065] OpenMP requires: "If a teams region is nested inside a target region, the corresponding target construct must not contain any statements, declarations or directives outside of the corresponding teams construct." This commit checks now for this restriction. PR fortran/110725 PR middle-end/71065 gcc/fortran/ChangeLog: * gfortran.h (gfc_omp_clauses): Add contains_teams_construct. * openmp.cc (resolve_omp_target): New; check for teams nesting. (gfc_resolve_omp_directive): Call it. * parse.cc (decode_omp_directive): Set contains_teams_construct on enclosing ST_OMP_TARGET. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/pr99226.f90: Update dg-error. * gfortran.dg/gomp/teams-5.f90: New test. --- gcc/fortran/gfortran.h | 1 + gcc/fortran/openmp.cc | 39 +++- gcc/fortran/parse.cc | 33 +++ gcc/testsuite/gfortran.dg/gomp/pr99226.f90 | 2 +- gcc/testsuite/gfortran.dg/gomp/teams-5.f90 | 150 + 5 files changed, 223 insertions(+), 2 deletions(-) diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 6482a885211..577ef807af7 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1575,6 +1575,7 @@ typedef struct gfc_omp_clauses unsigned order_unconstrained:1, order_reproducible:1, capture:1; unsigned grainsize_strict:1, num_tasks_strict:1, compare:1, weak:1; unsigned non_rectangular:1, order_concurrent:1; + unsigned contains_teams_construct:1; ENUM_BITFIELD (gfc_omp_sched_kind) sched_kind:3; ENUM_BITFIELD (gfc_omp_device_type) device_type:2; ENUM_BITFIELD (gfc_omp_memorder) memorder:3; diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc index 05a697da071..675011a18ce 100644 --- a/gcc/fortran/openmp.cc +++ b/gcc/fortran/openmp.cc @@ -10653,6 +10653,41 @@ gfc_resolve_oacc_directive (gfc_code *code, gfc_namespace *ns ATTRIBUTE_UNUSED) } +static void +resolve_omp_target (gfc_code *code) +{ +#define GFC_IS_TEAMS_CONSTRUCT(op) \ + (op == EXEC_OMP_TEAMS \ + || op == EXEC_OMP_TEAMS_DISTRIBUTE \ + || op == EXEC_OMP_TEAMS_DISTRIBUTE_SIMD \ + || op == EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO \ + || op == EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD \ + || op == EXEC_OMP_TEAMS_LOOP) + + if (!code->
[patch] OpenMP/Fortran: Reject declarations between target + teams (was: [Patch] OpenMP/Fortran: Reject not strictly nested target -> teams [PR110725, PR71065])
On 24.07.23 21:49, Jakub Jelinek via Fortran wrote: On Mon, Jul 24, 2023 at 09:43:10PM +0200, Tobias Burnus wrote: This patch adds diagnostic for additional code alongside a nested teams in a target region. Thanks for working on this. The fuzzy thing on the Fortran side is if e.g. multiple nested BLOCK statements can appear sandwiched in between target and teams (of course without declarations in them) Talking about declarations, I realized that I missed to diagnose them; the attached patch should handle them as well. (Except for 'omp nothing' and 'omp error', which return ST_NONE.) Comments, remarks, suggestions? If none or no changes are required, I will later commit the attached follow-up patch. 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: Reject declarations between target + teams While commit r14-2754-g2e31fe431b08b0302e1fa8a1c18ee51adafd41df detected executable statements, declarations do not show up as executable statements. Hence, we now check whether the first statement after TARGET is TEAMS - such that we can detect data statements like type or variable declarations. Fortran semantics ensures that only executable directives/statemens can come after '!$omp end teams' such that those can be detected with the previous check. Note that statements returning ST_NONE such as 'omp nothing' or 'omp error at(compilation)' will still slip through. PR fortran/110725 PR middle-end/71065 gcc/fortran/ChangeLog: * gfortran.h (gfc_omp_clauses): Add target_first_st_is_teams. * parse.cc (parse_omp_structured_block): Set it if the first statement in the structured block of a TARGET is TEAMS or a combined/composite starting with TEAMS. * openmp.cc (resolve_omp_target): Also show an error for contains_teams_construct without target_first_st_is_teams. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/teams-6.f90: New test. gcc/fortran/gfortran.h | 2 +- gcc/fortran/openmp.cc | 13 ++--- gcc/fortran/parse.cc | 25 -- gcc/testsuite/gfortran.dg/gomp/teams-6.f90 | 78 ++ 4 files changed, 108 insertions(+), 10 deletions(-) diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 577ef807af7..9a00e6dea6f 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1575,7 +1575,7 @@ typedef struct gfc_omp_clauses unsigned order_unconstrained:1, order_reproducible:1, capture:1; unsigned grainsize_strict:1, num_tasks_strict:1, compare:1, weak:1; unsigned non_rectangular:1, order_concurrent:1; - unsigned contains_teams_construct:1; + unsigned contains_teams_construct:1, target_first_st_is_teams:1; ENUM_BITFIELD (gfc_omp_sched_kind) sched_kind:3; ENUM_BITFIELD (gfc_omp_device_type) device_type:2; ENUM_BITFIELD (gfc_omp_memorder) memorder:3; diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc index 675011a18ce..52eeaf2d4da 100644 --- a/gcc/fortran/openmp.cc +++ b/gcc/fortran/openmp.cc @@ -10666,12 +10666,13 @@ resolve_omp_target (gfc_code *code) if (!code->ext.omp_clauses->contains_teams_construct) return; - if ((GFC_IS_TEAMS_CONSTRUCT (code->block->next->op) - && code->block->next->next == NULL) - || (code->block->next->op == EXEC_BLOCK - && code->block->next->next - && GFC_IS_TEAMS_CONSTRUCT (code->block->next->next->op) - && code->block->next->next->next == NULL)) + if (code->ext.omp_clauses->target_first_st_is_teams + && ((GFC_IS_TEAMS_CONSTRUCT (code->block->next->op) + && code->block->next->next == NULL) + || (code->block->next->op == EXEC_BLOCK + && code->block->next->next + && GFC_IS_TEAMS_CONSTRUCT (code->block->next->next->op) + && code->block->next->next->next == NULL))) return; gfc_code *c = code->block->next; while (c && !GFC_IS_TEAMS_CONSTRUCT (c->op)) diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc index 011a39c3d04..aa6bb663def 100644 --- a/gcc/fortran/parse.cc +++ b/gcc/fortran/parse.cc @@ -5766,7 +5766,7 @@ parse_openmp_allocate_block (gfc_statement omp_st) static gfc_statement parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only) { - gfc_statement st, omp_end_st; + gfc_statement st, omp_end_st, first_st; gfc_code *cp, *np; gfc_state_data s; @@ -5857,7 +5857,7 @@ parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only) gfc_namespace *my_ns = NULL; gfc_namespace *my_parent = NULL; - st = next_statement (); + first_st = st = next_statement (); if (st == ST_BLOCK) { @@ -5876,9 +5876,28 @@ parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only) new_st.ext.block.ns = my_ns; new_st.ext.block.assoc = NULL; accept_statement (S