From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1534) id 7D8A83857816; Tue, 1 Jun 2021 10:48:22 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7D8A83857816 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Tobias Burnus To: gcc-cvs@gcc.gnu.org Subject: [gcc r12-1139] Fortran/OpenMP: Support (parallel) master taskloop (simd) [PR99928] X-Act-Checkin: gcc X-Git-Author: Tobias Burnus X-Git-Refname: refs/heads/master X-Git-Oldrev: 28daadc98094501175c9dfe4a985871fa6aa4f94 X-Git-Newrev: f6bf436d9ab907d090823895abb7a2d5ba7ff50c Message-Id: <20210601104822.7D8A83857816@sourceware.org> Date: Tue, 1 Jun 2021 10:48:22 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 01 Jun 2021 10:48:22 -0000 https://gcc.gnu.org/g:f6bf436d9ab907d090823895abb7a2d5ba7ff50c commit r12-1139-gf6bf436d9ab907d090823895abb7a2d5ba7ff50c Author: Tobias Burnus Date: Tue Jun 1 12:46:37 2021 +0200 Fortran/OpenMP: Support (parallel) master taskloop (simd) [PR99928] PR middle-end/99928 gcc/fortran/ChangeLog: * dump-parse-tree.c (show_omp_node, show_code_node): Handle (parallel) master taskloop (simd). * frontend-passes.c (gfc_code_walker): Set in_omp_workshare to false for parallel master taskloop (simd). * gfortran.h (enum gfc_statement): Add ST_OMP_(END_)(PARALLEL_)MASTER_TASKLOOP(_SIMD). (enum gfc_exec_op): EXEC_OMP_(PARALLEL_)MASTER_TASKLOOP(_SIMD). * match.h (gfc_match_omp_master_taskloop, gfc_match_omp_master_taskloop_simd, gfc_match_omp_parallel_master_taskloop, gfc_match_omp_parallel_master_taskloop_simd): New prototype. * openmp.c (gfc_match_omp_parallel_master_taskloop, gfc_match_omp_parallel_master_taskloop_simd, gfc_match_omp_master_taskloop, gfc_match_omp_master_taskloop_simd): New. (gfc_match_omp_taskloop_simd): Permit 'reduction' clause. (resolve_omp_clauses): Handle new combined directives; remove inscan-reduction check to reduce multiple errors; add task-reduction error for 'taskloop simd'. (gfc_resolve_omp_parallel_blocks, resolve_omp_do, omp_code_to_statement, gfc_resolve_omp_directive): Handle new combined constructs. * parse.c (decode_omp_directive, next_statement, gfc_ascii_statement, parse_omp_do, parse_omp_structured_block, parse_executable): Likewise. * resolve.c (gfc_resolve_blocks, gfc_resolve_code): Likewise. * st.c (gfc_free_statement): Likewise. * trans.c (trans_code): Likewise. * trans-openmp.c (gfc_split_omp_clauses, gfc_trans_omp_directive): Likewise. (gfc_trans_omp_parallel_master): Move after gfc_trans_omp_master_taskloop; handle parallel master taskloop (simd) as well. (gfc_trans_omp_taskloop): Take gfc_exec_op as arg. (gfc_trans_omp_master_taskloop): New. gcc/testsuite/ChangeLog: * gfortran.dg/gomp/reduction5.f90: Remove dg-error; the issue is now diagnosed with less error output. * gfortran.dg/gomp/scan-1.f90: Likewise. * gfortran.dg/gomp/pr99928-3.f90: New test. * gfortran.dg/gomp/taskloop-1.f90: New test. Diff: --- gcc/fortran/dump-parse-tree.c | 12 +++ gcc/fortran/frontend-passes.c | 2 + gcc/fortran/gfortran.h | 10 +- gcc/fortran/match.h | 4 + gcc/fortran/openmp.c | 85 ++++++++++++++-- gcc/fortran/parse.c | 73 +++++++++++++- gcc/fortran/resolve.c | 10 ++ gcc/fortran/st.c | 4 + gcc/fortran/trans-openmp.c | 112 ++++++++++++++++----- gcc/fortran/trans.c | 4 + gcc/testsuite/gfortran.dg/gomp/pr99928-3.f90 | 139 ++++++++++++++++++++++++++ gcc/testsuite/gfortran.dg/gomp/reduction5.f90 | 4 +- gcc/testsuite/gfortran.dg/gomp/scan-1.f90 | 4 +- gcc/testsuite/gfortran.dg/gomp/taskloop-1.f90 | 126 +++++++++++++++++++++++ 14 files changed, 550 insertions(+), 39 deletions(-) diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c index 93ff572cbd2..0e7fe1cc3f3 100644 --- a/gcc/fortran/dump-parse-tree.c +++ b/gcc/fortran/dump-parse-tree.c @@ -1898,12 +1898,18 @@ show_omp_node (int level, gfc_code *c) case EXEC_OMP_DO_SIMD: name = "DO SIMD"; break; case EXEC_OMP_FLUSH: name = "FLUSH"; break; case EXEC_OMP_MASTER: name = "MASTER"; break; + case EXEC_OMP_MASTER_TASKLOOP: name = "MASTER TASKLOOP"; break; + case EXEC_OMP_MASTER_TASKLOOP_SIMD: name = "MASTER TASKLOOP SIMD"; break; case EXEC_OMP_ORDERED: name = "ORDERED"; break; case EXEC_OMP_DEPOBJ: name = "DEPOBJ"; break; case EXEC_OMP_PARALLEL: name = "PARALLEL"; break; case EXEC_OMP_PARALLEL_DO: name = "PARALLEL DO"; break; case EXEC_OMP_PARALLEL_DO_SIMD: name = "PARALLEL DO SIMD"; break; case EXEC_OMP_PARALLEL_MASTER: name = "PARALLEL MASTER"; break; + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP: + name = "PARALLEL MASTER TASKLOOP"; break; + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD: + name = "PARALLEL MASTER TASKLOOP SIMD"; break; case EXEC_OMP_PARALLEL_SECTIONS: name = "PARALLEL SECTIONS"; break; case EXEC_OMP_PARALLEL_WORKSHARE: name = "PARALLEL WORKSHARE"; break; case EXEC_OMP_SCAN: name = "SCAN"; break; @@ -1976,6 +1982,8 @@ show_omp_node (int level, gfc_code *c) case EXEC_OMP_PARALLEL_DO: case EXEC_OMP_PARALLEL_DO_SIMD: case EXEC_OMP_PARALLEL_MASTER: + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP: + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD: case EXEC_OMP_PARALLEL_SECTIONS: case EXEC_OMP_PARALLEL_WORKSHARE: case EXEC_OMP_SCAN: @@ -3184,11 +3192,15 @@ show_code_node (int level, gfc_code *c) case EXEC_OMP_DO_SIMD: case EXEC_OMP_FLUSH: case EXEC_OMP_MASTER: + case EXEC_OMP_MASTER_TASKLOOP: + case EXEC_OMP_MASTER_TASKLOOP_SIMD: case EXEC_OMP_ORDERED: case EXEC_OMP_PARALLEL: case EXEC_OMP_PARALLEL_DO: case EXEC_OMP_PARALLEL_DO_SIMD: case EXEC_OMP_PARALLEL_MASTER: + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP: + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD: case EXEC_OMP_PARALLEL_SECTIONS: case EXEC_OMP_PARALLEL_WORKSHARE: case EXEC_OMP_SCAN: diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c index ffe2db4881d..e3b1d1544aa 100644 --- a/gcc/fortran/frontend-passes.c +++ b/gcc/fortran/frontend-passes.c @@ -5543,6 +5543,8 @@ gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn, case EXEC_OMP_PARALLEL_DO: case EXEC_OMP_PARALLEL_DO_SIMD: case EXEC_OMP_PARALLEL_MASTER: + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP: + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD: case EXEC_OMP_PARALLEL_SECTIONS: in_omp_workshare = false; diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 55fba04642a..2020ab4a503 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -267,7 +267,11 @@ enum gfc_statement ST_GET_FCN_CHARACTERISTICS, ST_LOCK, ST_UNLOCK, ST_EVENT_POST, ST_EVENT_WAIT, ST_FAIL_IMAGE, ST_FORM_TEAM, ST_CHANGE_TEAM, ST_END_TEAM, ST_SYNC_TEAM, ST_OMP_PARALLEL_MASTER, - ST_OMP_END_PARALLEL_MASTER, ST_NONE + ST_OMP_END_PARALLEL_MASTER, ST_OMP_PARALLEL_MASTER_TASKLOOP, + ST_OMP_END_PARALLEL_MASTER_TASKLOOP, ST_OMP_PARALLEL_MASTER_TASKLOOP_SIMD, + ST_OMP_END_PARALLEL_MASTER_TASKLOOP_SIMD, ST_OMP_MASTER_TASKLOOP, + ST_OMP_END_MASTER_TASKLOOP, ST_OMP_MASTER_TASKLOOP_SIMD, + ST_OMP_END_MASTER_TASKLOOP_SIMD, ST_NONE }; /* Types of interfaces that we can have. Assignment interfaces are @@ -2711,7 +2715,9 @@ enum gfc_exec_op EXEC_OMP_TARGET_PARALLEL, EXEC_OMP_TARGET_PARALLEL_DO, EXEC_OMP_TARGET_PARALLEL_DO_SIMD, EXEC_OMP_TARGET_SIMD, EXEC_OMP_TASKLOOP, EXEC_OMP_TASKLOOP_SIMD, EXEC_OMP_SCAN, EXEC_OMP_DEPOBJ, - EXEC_OMP_PARALLEL_MASTER + EXEC_OMP_PARALLEL_MASTER, EXEC_OMP_PARALLEL_MASTER_TASKLOOP, + EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD, EXEC_OMP_MASTER_TASKLOOP, + EXEC_OMP_MASTER_TASKLOOP_SIMD }; typedef struct gfc_code diff --git a/gcc/fortran/match.h b/gcc/fortran/match.h index 09c572324bc..bcedf8ef806 100644 --- a/gcc/fortran/match.h +++ b/gcc/fortran/match.h @@ -169,12 +169,16 @@ match gfc_match_omp_do (void); match gfc_match_omp_do_simd (void); match gfc_match_omp_flush (void); match gfc_match_omp_master (void); +match gfc_match_omp_master_taskloop (void); +match gfc_match_omp_master_taskloop_simd (void); match gfc_match_omp_ordered (void); match gfc_match_omp_ordered_depend (void); match gfc_match_omp_parallel (void); match gfc_match_omp_parallel_do (void); match gfc_match_omp_parallel_do_simd (void); match gfc_match_omp_parallel_master (void); +match gfc_match_omp_parallel_master_taskloop (void); +match gfc_match_omp_parallel_master_taskloop_simd (void); match gfc_match_omp_parallel_sections (void); match gfc_match_omp_parallel_workshare (void); match gfc_match_omp_requires (void); diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index 4ed6a0d64c8..9dba165f990 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -3995,6 +3995,22 @@ gfc_match_omp_parallel_master (void) return match_omp (EXEC_OMP_PARALLEL_MASTER, OMP_PARALLEL_CLAUSES); } +match +gfc_match_omp_parallel_master_taskloop (void) +{ + return match_omp (EXEC_OMP_PARALLEL_MASTER_TASKLOOP, + (OMP_PARALLEL_CLAUSES | OMP_TASKLOOP_CLAUSES) + & ~(omp_mask (OMP_CLAUSE_IN_REDUCTION))); +} + +match +gfc_match_omp_parallel_master_taskloop_simd (void) +{ + return match_omp (EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD, + (OMP_PARALLEL_CLAUSES | OMP_TASKLOOP_CLAUSES + | OMP_SIMD_CLAUSES) + & ~(omp_mask (OMP_CLAUSE_IN_REDUCTION))); +} match gfc_match_omp_parallel_sections (void) @@ -4429,8 +4445,7 @@ match gfc_match_omp_taskloop_simd (void) { return match_omp (EXEC_OMP_TASKLOOP_SIMD, - (OMP_TASKLOOP_CLAUSES | OMP_SIMD_CLAUSES) - & ~(omp_mask (OMP_CLAUSE_REDUCTION))); + OMP_TASKLOOP_CLAUSES | OMP_SIMD_CLAUSES); } @@ -4533,6 +4548,18 @@ gfc_match_omp_master (void) return MATCH_YES; } +match +gfc_match_omp_master_taskloop (void) +{ + return match_omp (EXEC_OMP_MASTER_TASKLOOP, OMP_TASKLOOP_CLAUSES); +} + +match +gfc_match_omp_master_taskloop_simd (void) +{ + return match_omp (EXEC_OMP_MASTER_TASKLOOP_SIMD, + OMP_TASKLOOP_CLAUSES | OMP_SIMD_CLAUSES); +} match gfc_match_omp_ordered (void) @@ -5073,6 +5100,16 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, ok = ifc == OMP_IF_PARALLEL || ifc == OMP_IF_SIMD; break; + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP: + ok = ifc == OMP_IF_PARALLEL || ifc == OMP_IF_TASKLOOP; + break; + + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD: + ok = (ifc == OMP_IF_PARALLEL + || ifc == OMP_IF_TASKLOOP + || ifc == OMP_IF_SIMD); + break; + case EXEC_OMP_SIMD: case EXEC_OMP_DO_SIMD: case EXEC_OMP_DISTRIBUTE_SIMD: @@ -5085,10 +5122,12 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, break; case EXEC_OMP_TASKLOOP: + case EXEC_OMP_MASTER_TASKLOOP: ok = ifc == OMP_IF_TASKLOOP; break; case EXEC_OMP_TASKLOOP_SIMD: + case EXEC_OMP_MASTER_TASKLOOP_SIMD: ok = ifc == OMP_IF_TASKLOOP || ifc == OMP_IF_SIMD; break; @@ -5848,11 +5887,16 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, n->sym->name, name, &n->where); switch (list) { - case OMP_LIST_REDUCTION_INSCAN: case OMP_LIST_REDUCTION_TASK: - if (code && (code->op == EXEC_OMP_TASKLOOP - || code->op == EXEC_OMP_TEAMS - || code->op == EXEC_OMP_TEAMS_DISTRIBUTE)) + if (code + && (code->op == EXEC_OMP_TASKLOOP + || code->op == EXEC_OMP_TASKLOOP_SIMD + || code->op == EXEC_OMP_MASTER_TASKLOOP + || code->op == EXEC_OMP_MASTER_TASKLOOP_SIMD + || code->op == EXEC_OMP_PARALLEL_MASTER_TASKLOOP + || code->op == EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD + || code->op == EXEC_OMP_TEAMS + || code->op == EXEC_OMP_TEAMS_DISTRIBUTE)) { gfc_error ("Only DEFAULT permitted as reduction-" "modifier in REDUCTION clause at %L", @@ -5863,6 +5907,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses, case OMP_LIST_REDUCTION: case OMP_LIST_IN_REDUCTION: case OMP_LIST_TASK_REDUCTION: + case OMP_LIST_REDUCTION_INSCAN: switch (n->u.reduction_op) { case OMP_REDUCTION_PLUS: @@ -6766,6 +6811,10 @@ gfc_resolve_omp_parallel_blocks (gfc_code *code, gfc_namespace *ns) case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD: case EXEC_OMP_PARALLEL_DO: case EXEC_OMP_PARALLEL_DO_SIMD: + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP: + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD: + case EXEC_OMP_MASTER_TASKLOOP: + case EXEC_OMP_MASTER_TASKLOOP_SIMD: case EXEC_OMP_TARGET_PARALLEL_DO: case EXEC_OMP_TARGET_PARALLEL_DO_SIMD: case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE: @@ -6909,6 +6958,18 @@ resolve_omp_do (gfc_code *code) name = "!$OMP PARALLEL DO SIMD"; is_simd = true; break; + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP: + name = "!$OMP PARALLEL MASTER TASKLOOP"; + break; + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD: + name = "!$OMP PARALLEL MASTER TASKLOOP SIMD"; + is_simd = true; + break; + case EXEC_OMP_MASTER_TASKLOOP: name = "!$OMP MASTER TASKLOOP"; break; + case EXEC_OMP_MASTER_TASKLOOP_SIMD: + name = "!$OMP MASTER TASKLOOP SIMD"; + is_simd = true; + break; case EXEC_OMP_SIMD: name = "!$OMP SIMD"; is_simd = true; break; case EXEC_OMP_TARGET_PARALLEL_DO: name = "!$OMP TARGET PARALLEL DO"; break; case EXEC_OMP_TARGET_PARALLEL_DO_SIMD: @@ -7063,6 +7124,10 @@ omp_code_to_statement (gfc_code *code) return ST_OMP_PARALLEL; case EXEC_OMP_PARALLEL_MASTER: return ST_OMP_PARALLEL_MASTER; + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP: + return ST_OMP_PARALLEL_MASTER_TASKLOOP; + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD: + return ST_OMP_PARALLEL_MASTER_TASKLOOP_SIMD; case EXEC_OMP_PARALLEL_SECTIONS: return ST_OMP_PARALLEL_SECTIONS; case EXEC_OMP_SECTIONS: @@ -7073,6 +7138,10 @@ omp_code_to_statement (gfc_code *code) return ST_OMP_CRITICAL; case EXEC_OMP_MASTER: return ST_OMP_MASTER; + case EXEC_OMP_MASTER_TASKLOOP: + return ST_OMP_MASTER_TASKLOOP; + case EXEC_OMP_MASTER_TASKLOOP_SIMD: + return ST_OMP_MASTER_TASKLOOP_SIMD; case EXEC_OMP_SINGLE: return ST_OMP_SINGLE; case EXEC_OMP_TASK: @@ -7561,6 +7630,10 @@ gfc_resolve_omp_directive (gfc_code *code, gfc_namespace *ns) case EXEC_OMP_DO_SIMD: case EXEC_OMP_PARALLEL_DO: case EXEC_OMP_PARALLEL_DO_SIMD: + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP: + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD: + case EXEC_OMP_MASTER_TASKLOOP: + case EXEC_OMP_MASTER_TASKLOOP_SIMD: case EXEC_OMP_SIMD: case EXEC_OMP_TARGET_PARALLEL_DO: case EXEC_OMP_TARGET_PARALLEL_DO_SIMD: diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c index 6efb3fd5e7b..c44e23ccb62 100644 --- a/gcc/fortran/parse.c +++ b/gcc/fortran/parse.c @@ -920,11 +920,19 @@ decode_omp_directive (void) matchs ("end do simd", gfc_match_omp_end_nowait, ST_OMP_END_DO_SIMD); matcho ("end do", gfc_match_omp_end_nowait, ST_OMP_END_DO); matchs ("end simd", gfc_match_omp_eos_error, ST_OMP_END_SIMD); + matcho ("end master taskloop simd", gfc_match_omp_eos_error, + ST_OMP_END_MASTER_TASKLOOP_SIMD); + matcho ("end master taskloop", gfc_match_omp_eos_error, + ST_OMP_END_MASTER_TASKLOOP); matcho ("end master", gfc_match_omp_eos_error, ST_OMP_END_MASTER); 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 master taskloop simd", gfc_match_omp_eos_error, + ST_OMP_END_PARALLEL_MASTER_TASKLOOP_SIMD); + matcho ("end parallel master taskloop", gfc_match_omp_eos_error, + ST_OMP_END_PARALLEL_MASTER_TASKLOOP); matcho ("end parallel master", gfc_match_omp_eos_error, ST_OMP_END_PARALLEL_MASTER); matcho ("end parallel sections", gfc_match_omp_eos_error, @@ -974,6 +982,10 @@ decode_omp_directive (void) matcho ("flush", gfc_match_omp_flush, ST_OMP_FLUSH); break; case 'm': + matcho ("master taskloop simd", gfc_match_omp_master_taskloop_simd, + ST_OMP_MASTER_TASKLOOP_SIMD); + matcho ("master taskloop", gfc_match_omp_master_taskloop, + ST_OMP_MASTER_TASKLOOP); matcho ("master", gfc_match_omp_master, ST_OMP_MASTER); break; case 'o': @@ -992,6 +1004,12 @@ decode_omp_directive (void) matchs ("parallel do simd", gfc_match_omp_parallel_do_simd, ST_OMP_PARALLEL_DO_SIMD); matcho ("parallel do", gfc_match_omp_parallel_do, ST_OMP_PARALLEL_DO); + matcho ("parallel master taskloop simd", + gfc_match_omp_parallel_master_taskloop_simd, + ST_OMP_PARALLEL_MASTER_TASKLOOP_SIMD); + matcho ("parallel master taskloop", + gfc_match_omp_parallel_master_taskloop, + ST_OMP_PARALLEL_MASTER_TASKLOOP); matcho ("parallel master", gfc_match_omp_parallel_master, ST_OMP_PARALLEL_MASTER); matcho ("parallel sections", gfc_match_omp_parallel_sections, @@ -1610,8 +1628,11 @@ next_statement (void) case ST_IF_BLOCK: case ST_BLOCK: case ST_ASSOCIATE: \ case ST_WHERE_BLOCK: case ST_SELECT_CASE: case ST_SELECT_TYPE: \ case ST_SELECT_RANK: case ST_OMP_PARALLEL: case ST_OMP_PARALLEL_MASTER: \ + case ST_OMP_PARALLEL_MASTER_TASKLOOP: \ + case ST_OMP_PARALLEL_MASTER_TASKLOOP_SIMD: \ case ST_OMP_PARALLEL_SECTIONS: case ST_OMP_SECTIONS: case ST_OMP_ORDERED: \ - case ST_OMP_CRITICAL: case ST_OMP_MASTER: case ST_OMP_SINGLE: \ + case ST_OMP_CRITICAL: case ST_OMP_MASTER: case ST_OMP_MASTER_TASKLOOP: \ + case ST_OMP_MASTER_TASKLOOP_SIMD: case ST_OMP_SINGLE: \ case ST_OMP_DO: case ST_OMP_PARALLEL_DO: case ST_OMP_ATOMIC: \ case ST_OMP_WORKSHARE: case ST_OMP_PARALLEL_WORKSHARE: \ case ST_OMP_TASK: case ST_OMP_TASKGROUP: case ST_OMP_SIMD: \ @@ -2341,6 +2362,12 @@ gfc_ascii_statement (gfc_statement st) case ST_OMP_END_MASTER: p = "!$OMP END MASTER"; break; + case ST_OMP_END_MASTER_TASKLOOP: + p = "!$OMP END MASTER TASKLOOP"; + break; + case ST_OMP_END_MASTER_TASKLOOP_SIMD: + p = "!$OMP END MASTER TASKLOOP SIMD"; + break; case ST_OMP_END_ORDERED: p = "!$OMP END ORDERED"; break; @@ -2356,6 +2383,12 @@ gfc_ascii_statement (gfc_statement st) case ST_OMP_END_PARALLEL_MASTER: p = "!$OMP END PARALLEL MASTER"; break; + case ST_OMP_END_PARALLEL_MASTER_TASKLOOP: + p = "!$OMP END PARALLEL MASTER TASKLOOP"; + break; + case ST_OMP_END_PARALLEL_MASTER_TASKLOOP_SIMD: + p = "!$OMP END PARALLEL MASTER TASKLOOP SIMD"; + break; case ST_OMP_END_PARALLEL_SECTIONS: p = "!$OMP END PARALLEL SECTIONS"; break; @@ -2437,6 +2470,12 @@ gfc_ascii_statement (gfc_statement st) case ST_OMP_MASTER: p = "!$OMP MASTER"; break; + case ST_OMP_MASTER_TASKLOOP: + p = "!$OMP MASTER TASKLOOP"; + break; + case ST_OMP_MASTER_TASKLOOP_SIMD: + p = "!$OMP MASTER TASKLOOP SIMD"; + break; case ST_OMP_ORDERED: case ST_OMP_ORDERED_DEPEND: p = "!$OMP ORDERED"; @@ -2453,6 +2492,12 @@ gfc_ascii_statement (gfc_statement st) case ST_OMP_PARALLEL_MASTER: p = "!$OMP PARALLEL MASTER"; break; + case ST_OMP_PARALLEL_MASTER_TASKLOOP: + p = "!$OMP PARALLEL MASTER TASKLOOP"; + break; + case ST_OMP_PARALLEL_MASTER_TASKLOOP_SIMD: + p = "!$OMP PARALLEL MASTER TASKLOOP SIMD"; + break; case ST_OMP_PARALLEL_SECTIONS: p = "!$OMP PARALLEL SECTIONS"; break; @@ -5025,6 +5070,16 @@ parse_omp_do (gfc_statement omp_st) break; case ST_OMP_TASKLOOP: omp_end_st = ST_OMP_END_TASKLOOP; break; case ST_OMP_TASKLOOP_SIMD: omp_end_st = ST_OMP_END_TASKLOOP_SIMD; break; + case ST_OMP_MASTER_TASKLOOP: omp_end_st = ST_OMP_END_MASTER_TASKLOOP; break; + case ST_OMP_MASTER_TASKLOOP_SIMD: + omp_end_st = ST_OMP_END_MASTER_TASKLOOP_SIMD; + break; + case ST_OMP_PARALLEL_MASTER_TASKLOOP: + omp_end_st = ST_OMP_END_PARALLEL_MASTER_TASKLOOP; + break; + case ST_OMP_PARALLEL_MASTER_TASKLOOP_SIMD: + omp_end_st = ST_OMP_END_PARALLEL_MASTER_TASKLOOP_SIMD; + break; case ST_OMP_TEAMS_DISTRIBUTE: omp_end_st = ST_OMP_END_TEAMS_DISTRIBUTE; break; @@ -5268,6 +5323,12 @@ parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only) case ST_OMP_PARALLEL_MASTER: omp_end_st = ST_OMP_END_PARALLEL_MASTER; break; + case ST_OMP_PARALLEL_MASTER_TASKLOOP: + omp_end_st = ST_OMP_END_PARALLEL_MASTER_TASKLOOP; + break; + case ST_OMP_PARALLEL_MASTER_TASKLOOP_SIMD: + omp_end_st = ST_OMP_END_PARALLEL_MASTER_TASKLOOP_SIMD; + break; case ST_OMP_PARALLEL_SECTIONS: omp_end_st = ST_OMP_END_PARALLEL_SECTIONS; break; @@ -5283,6 +5344,12 @@ parse_omp_structured_block (gfc_statement omp_st, bool workshare_stmts_only) case ST_OMP_MASTER: omp_end_st = ST_OMP_END_MASTER; break; + case ST_OMP_MASTER_TASKLOOP: + omp_end_st = ST_OMP_END_MASTER_TASKLOOP; + break; + case ST_OMP_MASTER_TASKLOOP_SIMD: + omp_end_st = ST_OMP_END_MASTER_TASKLOOP_SIMD; + break; case ST_OMP_SINGLE: omp_end_st = ST_OMP_END_SINGLE; break; @@ -5624,6 +5691,10 @@ parse_executable (gfc_statement st) case ST_OMP_DO_SIMD: case ST_OMP_PARALLEL_DO: case ST_OMP_PARALLEL_DO_SIMD: + case ST_OMP_PARALLEL_MASTER_TASKLOOP: + case ST_OMP_PARALLEL_MASTER_TASKLOOP_SIMD: + case ST_OMP_MASTER_TASKLOOP: + case ST_OMP_MASTER_TASKLOOP_SIMD: case ST_OMP_SIMD: case ST_OMP_TARGET_PARALLEL_DO: case ST_OMP_TARGET_PARALLEL_DO_SIMD: diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 747516fbc1d..fed6dce3d98 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -10798,11 +10798,15 @@ gfc_resolve_blocks (gfc_code *b, gfc_namespace *ns) case EXEC_OMP_DO: case EXEC_OMP_DO_SIMD: case EXEC_OMP_MASTER: + case EXEC_OMP_MASTER_TASKLOOP: + case EXEC_OMP_MASTER_TASKLOOP_SIMD: case EXEC_OMP_ORDERED: case EXEC_OMP_PARALLEL: case EXEC_OMP_PARALLEL_DO: case EXEC_OMP_PARALLEL_DO_SIMD: case EXEC_OMP_PARALLEL_MASTER: + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP: + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD: case EXEC_OMP_PARALLEL_SECTIONS: case EXEC_OMP_PARALLEL_WORKSHARE: case EXEC_OMP_SECTIONS: @@ -11765,6 +11769,8 @@ gfc_resolve_code (gfc_code *code, gfc_namespace *ns) case EXEC_OMP_PARALLEL_DO: case EXEC_OMP_PARALLEL_DO_SIMD: case EXEC_OMP_PARALLEL_MASTER: + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP: + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD: case EXEC_OMP_PARALLEL_SECTIONS: case EXEC_OMP_TARGET_PARALLEL: case EXEC_OMP_TARGET_PARALLEL_DO: @@ -12214,6 +12220,8 @@ start: case EXEC_OMP_DO: case EXEC_OMP_DO_SIMD: case EXEC_OMP_MASTER: + case EXEC_OMP_MASTER_TASKLOOP: + case EXEC_OMP_MASTER_TASKLOOP_SIMD: case EXEC_OMP_ORDERED: case EXEC_OMP_SCAN: case EXEC_OMP_SECTIONS: @@ -12252,6 +12260,8 @@ start: case EXEC_OMP_PARALLEL_DO: case EXEC_OMP_PARALLEL_DO_SIMD: case EXEC_OMP_PARALLEL_MASTER: + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP: + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD: case EXEC_OMP_PARALLEL_SECTIONS: case EXEC_OMP_PARALLEL_WORKSHARE: omp_workshare_save = omp_workshare_flag; diff --git a/gcc/fortran/st.c b/gcc/fortran/st.c index 7d0e2c14731..9f6fe49db02 100644 --- a/gcc/fortran/st.c +++ b/gcc/fortran/st.c @@ -226,11 +226,15 @@ gfc_free_statement (gfc_code *p) case EXEC_OMP_DO: case EXEC_OMP_DO_SIMD: case EXEC_OMP_END_SINGLE: + case EXEC_OMP_MASTER_TASKLOOP: + case EXEC_OMP_MASTER_TASKLOOP_SIMD: case EXEC_OMP_ORDERED: case EXEC_OMP_PARALLEL: case EXEC_OMP_PARALLEL_DO: case EXEC_OMP_PARALLEL_DO_SIMD: case EXEC_OMP_PARALLEL_MASTER: + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP: + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD: case EXEC_OMP_PARALLEL_SECTIONS: case EXEC_OMP_PARALLEL_WORKSHARE: case EXEC_OMP_SCAN: diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index 7ea7aa37efd..2917d3d058b 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -5380,6 +5380,14 @@ gfc_split_omp_clauses (gfc_code *code, mask = GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_DO | GFC_OMP_MASK_SIMD; innermost = GFC_OMP_SPLIT_SIMD; break; + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP: + mask = GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_TASKLOOP | GFC_OMP_MASK_SIMD; + innermost = GFC_OMP_SPLIT_TASKLOOP; + break; + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD: + mask = GFC_OMP_MASK_PARALLEL | GFC_OMP_MASK_TASKLOOP | GFC_OMP_MASK_SIMD; + innermost = GFC_OMP_SPLIT_SIMD; + break; case EXEC_OMP_SIMD: innermost = GFC_OMP_SPLIT_SIMD; break; @@ -5427,9 +5435,11 @@ gfc_split_omp_clauses (gfc_code *code, | GFC_OMP_MASK_DISTRIBUTE | GFC_OMP_MASK_SIMD; innermost = GFC_OMP_SPLIT_SIMD; break; + case EXEC_OMP_MASTER_TASKLOOP: case EXEC_OMP_TASKLOOP: innermost = GFC_OMP_SPLIT_TASKLOOP; break; + case EXEC_OMP_MASTER_TASKLOOP_SIMD: case EXEC_OMP_TASKLOOP_SIMD: mask = GFC_OMP_MASK_TASKLOOP | GFC_OMP_MASK_SIMD; innermost = GFC_OMP_SPLIT_SIMD; @@ -5820,28 +5830,6 @@ gfc_trans_omp_parallel_do_simd (gfc_code *code, stmtblock_t *pblock, return gfc_finish_block (&block); } -static tree -gfc_trans_omp_parallel_master (gfc_code *code) -{ - stmtblock_t block; - tree stmt, omp_clauses; - - gfc_start_block (&block); - omp_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses, - code->loc); - pushlevel (); - stmt = gfc_trans_omp_master (code); - if (TREE_CODE (stmt) != BIND_EXPR) - stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0)); - else - poplevel (0, 0); - stmt = build2_loc (gfc_get_location (&code->loc), OMP_PARALLEL, - void_type_node, stmt, omp_clauses); - OMP_PARALLEL_COMBINED (stmt) = 1; - gfc_add_expr_to_block (&block, stmt); - return gfc_finish_block (&block); -} - static tree gfc_trans_omp_parallel_sections (gfc_code *code) { @@ -6217,7 +6205,7 @@ gfc_trans_omp_target (gfc_code *code) } static tree -gfc_trans_omp_taskloop (gfc_code *code) +gfc_trans_omp_taskloop (gfc_code *code, gfc_exec_op op) { stmtblock_t block; gfc_omp_clauses clausesa[GFC_OMP_SPLIT_NUM]; @@ -6229,7 +6217,7 @@ gfc_trans_omp_taskloop (gfc_code *code) omp_clauses = gfc_trans_omp_clauses (&block, &clausesa[GFC_OMP_SPLIT_TASKLOOP], code->loc); - switch (code->op) + switch (op) { case EXEC_OMP_TASKLOOP: /* This is handled in gfc_trans_omp_do. */ @@ -6258,6 +6246,75 @@ gfc_trans_omp_taskloop (gfc_code *code) return gfc_finish_block (&block); } +static tree +gfc_trans_omp_master_taskloop (gfc_code *code, gfc_exec_op op) +{ + stmtblock_t block; + tree stmt; + + gfc_start_block (&block); + pushlevel (); + if (op == EXEC_OMP_MASTER_TASKLOOP_SIMD) + stmt = gfc_trans_omp_taskloop (code, EXEC_OMP_TASKLOOP_SIMD); + else + { + gfc_omp_clauses clausesa[GFC_OMP_SPLIT_NUM]; + gcc_assert (op == EXEC_OMP_MASTER_TASKLOOP); + if (op != code->op) + gfc_split_omp_clauses (code, clausesa); + stmt = gfc_trans_omp_do (code, EXEC_OMP_TASKLOOP, NULL, + op != code->op + ? &clausesa[GFC_OMP_SPLIT_TASKLOOP] + : code->ext.omp_clauses, NULL); + } + if (TREE_CODE (stmt) != BIND_EXPR) + stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0)); + else + poplevel (0, 0); + stmt = build1_v (OMP_MASTER, stmt); + gfc_add_expr_to_block (&block, stmt); + return gfc_finish_block (&block); +} + +static tree +gfc_trans_omp_parallel_master (gfc_code *code) +{ + stmtblock_t block; + tree stmt, omp_clauses; + gfc_omp_clauses clausesa[GFC_OMP_SPLIT_NUM]; + + if (code->op != EXEC_OMP_PARALLEL_MASTER) + gfc_split_omp_clauses (code, clausesa); + + gfc_start_block (&block); + omp_clauses = gfc_trans_omp_clauses (&block, + code->op == EXEC_OMP_PARALLEL_MASTER + ? code->ext.omp_clauses + : &clausesa[GFC_OMP_SPLIT_PARALLEL], + code->loc); + pushlevel (); + if (code->op == EXEC_OMP_PARALLEL_MASTER) + stmt = gfc_trans_omp_master (code); + else + { + gcc_assert (code->op == EXEC_OMP_PARALLEL_MASTER_TASKLOOP + || code->op == EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD); + gfc_exec_op op = (code->op == EXEC_OMP_PARALLEL_MASTER_TASKLOOP + ? EXEC_OMP_MASTER_TASKLOOP + : EXEC_OMP_MASTER_TASKLOOP_SIMD); + stmt = gfc_trans_omp_master_taskloop (code, op); + } + if (TREE_CODE (stmt) != BIND_EXPR) + stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0)); + else + poplevel (0, 0); + stmt = build2_loc (gfc_get_location (&code->loc), OMP_PARALLEL, + void_type_node, stmt, omp_clauses); + OMP_PARALLEL_COMBINED (stmt) = 1; + gfc_add_expr_to_block (&block, stmt); + return gfc_finish_block (&block); +} + static tree gfc_trans_omp_target_data (gfc_code *code) { @@ -6568,6 +6625,9 @@ gfc_trans_omp_directive (gfc_code *code) return gfc_trans_omp_flush (code); case EXEC_OMP_MASTER: return gfc_trans_omp_master (code); + case EXEC_OMP_MASTER_TASKLOOP: + case EXEC_OMP_MASTER_TASKLOOP_SIMD: + return gfc_trans_omp_master_taskloop (code, code->op); case EXEC_OMP_ORDERED: return gfc_trans_omp_ordered (code); case EXEC_OMP_PARALLEL: @@ -6577,6 +6637,8 @@ gfc_trans_omp_directive (gfc_code *code) case EXEC_OMP_PARALLEL_DO_SIMD: return gfc_trans_omp_parallel_do_simd (code, NULL, NULL); case EXEC_OMP_PARALLEL_MASTER: + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP: + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD: return gfc_trans_omp_parallel_master (code); case EXEC_OMP_PARALLEL_SECTIONS: return gfc_trans_omp_parallel_sections (code); @@ -6610,7 +6672,7 @@ gfc_trans_omp_directive (gfc_code *code) case EXEC_OMP_TASKGROUP: return gfc_trans_omp_taskgroup (code); case EXEC_OMP_TASKLOOP_SIMD: - return gfc_trans_omp_taskloop (code); + return gfc_trans_omp_taskloop (code, code->op); case EXEC_OMP_TASKWAIT: return gfc_trans_omp_taskwait (code); case EXEC_OMP_TASKYIELD: diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c index 9f296bd8c03..cbbfcd9d1bc 100644 --- a/gcc/fortran/trans.c +++ b/gcc/fortran/trans.c @@ -2170,11 +2170,15 @@ trans_code (gfc_code * code, tree cond) case EXEC_OMP_DO_SIMD: case EXEC_OMP_FLUSH: case EXEC_OMP_MASTER: + case EXEC_OMP_MASTER_TASKLOOP: + case EXEC_OMP_MASTER_TASKLOOP_SIMD: case EXEC_OMP_ORDERED: case EXEC_OMP_PARALLEL: case EXEC_OMP_PARALLEL_DO: case EXEC_OMP_PARALLEL_DO_SIMD: case EXEC_OMP_PARALLEL_MASTER: + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP: + case EXEC_OMP_PARALLEL_MASTER_TASKLOOP_SIMD: case EXEC_OMP_PARALLEL_SECTIONS: case EXEC_OMP_PARALLEL_WORKSHARE: case EXEC_OMP_SECTIONS: diff --git a/gcc/testsuite/gfortran.dg/gomp/pr99928-3.f90 b/gcc/testsuite/gfortran.dg/gomp/pr99928-3.f90 new file mode 100644 index 00000000000..ce43dfb8ccd --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/pr99928-3.f90 @@ -0,0 +1,139 @@ +! PR middle-end/99928 +! { dg-do compile } +! { dg-options "-fopenmp -fdump-tree-gimple" } + +module m + implicit none + integer :: l00, l01, l02, l03, l04, l07, l08, l09 + integer :: l10, l11 + +contains + +subroutine bar () + integer :: l05, l06 + integer :: i + l05 = 0; l06 = 0 + ! { dg-final { scan-tree-dump "omp for\[^\n\r]*firstprivate\\(l00\\)" "gimple" } } + ! { dg-final { scan-tree-dump "omp for\[^\n\r]*lastprivate\\(l00\\)" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(l00\\)" "gimple" } } + ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l00\\)" "gimple" } } + !$omp do simd firstprivate (l00) lastprivate (l00) + do i = 1, 64 + l00 = i + end do + ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(l01\\)" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l01\\)" "gimple" } } + ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l01\\)" "gimple" } } + ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l01\\)" "gimple" } } + !$omp master taskloop firstprivate (l01) lastprivate (l01) + do i = 1, 64 + l01 = i + end do + ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(l02\\)" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l02\\)" "gimple" } } + ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l02\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l02\\)" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(l02\\)" "gimple" } } + ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l02\\)" "gimple" } } + !$omp master taskloop simd firstprivate (l02) lastprivate (l02) + do i = 1, 64 + l02 = i + end do + ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(l03\\)" "gimple" } } ! FIXME: This should be on for instead. + ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l03\\)" "gimple" } } ! FIXME: This should be on for instead. + ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(l03\\)" "gimple" } } ! FIXME. + ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l03\\)" "gimple" } } ! FIXME. + !$omp parallel do firstprivate (l03) lastprivate (l03) + do i = 1, 64 + l03 = i + end do + !$omp end parallel do + ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(l04\\)" "gimple" } } ! FIXME: This should be on for instead. + ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l04\\)" "gimple" } } ! FIXME: This should be on for instead. + ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(l04\\)" "gimple" } } ! FIXME. + ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l04\\)" "gimple" } } ! FIXME. + ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(l04\\)" "gimple" } } + ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l04\\)" "gimple" } } + !$omp parallel do simd firstprivate (l04) lastprivate (l04) + do i = 1, 64 + l04 = i + end do + !$omp end parallel do simd + ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(l05\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(l05\\)" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l05\\)" "gimple" } } + ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l05\\)" "gimple" } } + ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l05\\)" "gimple" { xfail *-*-* } } } + !$omp parallel master taskloop firstprivate (l05) lastprivate (l05) + do i = 1, 64 + l05 = i + end do + ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*shared\\(l06\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*firstprivate\\(l06\\)" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp master\[^\n\r]*lastprivate\\(l06\\)" "gimple" } } + ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l06\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l06\\)" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(l06\\)" "gimple" } } + ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l06\\)" "gimple" } } + !$omp parallel master taskloop simd firstprivate (l06) lastprivate (l06) + do i = 1, 64 + l06 = i + end do + !$omp end parallel master taskloop simd + ! FIXME: OpenMP 5.0/5.1 broken here, conceptually it should be shared on parallel and + ! firstprivate+lastprivate on sections, in GCC implementation we put firstprivate+lastprivate + ! on parallel for historic reasons, but OpenMP 5.0/5.1 mistakenly say firstprivate + ! should be on parallel and lastprivate on sections. + ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(l07\\)" "gimple" } } + ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l07\\)" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp sections\[^\n\r]*firstprivate\\(l07\\)" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp sections\[^\n\r]*lastprivate\\(l07\\)" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp section \[^\n\r]*firstprivate\\(l07\\)" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp section \[^\n\r]*lastprivate\\(l07\\)" "gimple" } } + !$omp parallel sections firstprivate (l07) lastprivate (l07) + l07 = 1 + !$omp section + l07 = 2 + !$omp end parallel sections + ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l08" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l08\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(l08\\)" "gimple" } } ! FIXME: This should be on for instead. + ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l08\\)" "gimple" } } ! FIXME: This should be on for instead. + ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(l08\\)" "gimple" } } ! FIXME. + ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l08\\)" "gimple" } } ! FIXME. + !$omp target parallel do firstprivate (l08) lastprivate (l08) + do i = 1, 64 + l08 = i + end do + !$omp end target parallel do + ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l09" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l09\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*firstprivate\\(l09\\)" "gimple" } } ! FIXME: This should be on for instead. + ! { dg-final { scan-tree-dump "omp parallel\[^\n\r]*lastprivate\\(l09\\)" "gimple" } } ! FIXME: This should be on for instead. + ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*firstprivate\\(l09\\)" "gimple" } } ! FIXME. + ! { dg-final { scan-tree-dump-not "omp for\[^\n\r]*lastprivate\\(l09\\)" "gimple" } } ! FIXME. + ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(l09\\)" "gimple" } } + ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l09\\)" "gimple" } } + !$omp target parallel do simd firstprivate (l09) lastprivate (l09) + do i = 1, 64 + l09 = i + end do + ! { dg-final { scan-tree-dump "omp target\[^\n\r]*map\\(tofrom:l10" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump-not "omp target\[^\n\r]*firstprivate\\(l10\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(l10\\)" "gimple" } } + ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l10\\)" "gimple" } } + !$omp target simd firstprivate (l10) lastprivate (l10) + do i = 1, 64 + l10 = i + end do + ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*firstprivate\\(l11\\)" "gimple" { xfail *-*-* } } } + ! { dg-final { scan-tree-dump "omp taskloop\[^\n\r]*lastprivate\\(l11\\)" "gimple" } } + ! { dg-final { scan-tree-dump-not "omp simd\[^\n\r]*firstprivate\\(l11\\)" "gimple" } } + ! { dg-final { scan-tree-dump "omp simd\[^\n\r]*lastprivate\\(l11\\)" "gimple" } } + !$omp taskloop simd firstprivate (l11) lastprivate (l11) + do i = 1, 64 + l11 = i + end do + !$omp end taskloop simd +end +end module m diff --git a/gcc/testsuite/gfortran.dg/gomp/reduction5.f90 b/gcc/testsuite/gfortran.dg/gomp/reduction5.f90 index 032703d3b81..44f89d84c78 100644 --- a/gcc/testsuite/gfortran.dg/gomp/reduction5.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/reduction5.f90 @@ -22,8 +22,7 @@ end do !$omp taskloop reduction(inscan,+:a) in_reduction(+:b) ! { dg-error "'inscan' REDUCTION clause on construct other than DO, SIMD, DO SIMD, PARALLEL DO, PARALLEL DO SIMD" } ! { dg-error "34: With INSCAN at .1., expected loop body with ..OMP SCAN between two structured-block-sequences" "" { target *-*-* } .-1 } - ! { dg-error "Only DEFAULT permitted as reduction-modifier in REDUCTION clause" "" { target *-*-* } .-2 } - ! { dg-error "'inscan' and non-'inscan' 'reduction' clauses on the same construct" "" { target *-*-* } .-3 } + ! { dg-error "'inscan' and non-'inscan' 'reduction' clauses on the same construct" "" { target *-*-* } .-2 } do i=1,10 a = a + 1 end do @@ -34,7 +33,6 @@ do i=1,10 end do !$omp teams reduction(inscan,+:b) ! { dg-error "'inscan' REDUCTION clause on construct other than DO, SIMD, DO SIMD, PARALLEL DO, PARALLEL DO SIMD" } - ! { dg-error "Only DEFAULT permitted as reduction-modifier in REDUCTION clause" "" { target *-*-* } .-1 } a = a + 1 !$omp end teams diff --git a/gcc/testsuite/gfortran.dg/gomp/scan-1.f90 b/gcc/testsuite/gfortran.dg/gomp/scan-1.f90 index 8c879fd98b9..61d89259c48 100644 --- a/gcc/testsuite/gfortran.dg/gomp/scan-1.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/scan-1.f90 @@ -100,7 +100,7 @@ subroutine f3 (c, d) use m implicit none integer i, c(64), d(64) - !$omp teams reduction (inscan, +: a) ! { dg-error "Only DEFAULT permitted as reduction-modifier in REDUCTION clause at" } + !$omp teams reduction (inscan, +: a) ! { dg-error "'inscan' REDUCTION clause on construct other than DO, SIMD, DO SIMD, PARALLEL DO, PARALLEL DO SIMD" "" { target *-*-* } .-1 } ! ... !$omp end teams @@ -135,7 +135,7 @@ subroutine f4 (c, d) use m implicit none integer i, c(64), d(64) - !$omp taskloop reduction (inscan, +: a) ! { dg-error "Only DEFAULT permitted as reduction-modifier in REDUCTION clause" } + !$omp taskloop reduction (inscan, +: a) ! { dg-error "'inscan' REDUCTION clause on construct other than DO, SIMD, DO SIMD, PARALLEL DO, PARALLEL DO SIMD" "" { target *-*-* } .-1 } do i = 1, 64 d(i) = a diff --git a/gcc/testsuite/gfortran.dg/gomp/taskloop-1.f90 b/gcc/testsuite/gfortran.dg/gomp/taskloop-1.f90 new file mode 100644 index 00000000000..7060a7a5c96 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/taskloop-1.f90 @@ -0,0 +1,126 @@ +module m + implicit none + integer :: t + !$omp threadprivate (t) + integer :: f, l, ll, r, r2 + !$omp declare target to(f, l, ll, r, r2) +end module m + +subroutine foo(fi, p, pp, g, s, nta, nth, ntm, i1, i2, i3, q) + use m + implicit none + integer, value :: p, pp, g, s, nta, nth, ntm + logical, value :: fi, i1, i2, i3 + integer, pointer :: q(:) + integer :: i + + !$omp taskgroup task_reduction(+:r2) !allocate (r2) + !$omp taskloop simd & + !$omp& private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) & + !$omp& if(simd: i2) final(fi) mergeable priority (pp) & + !$omp& safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm) & + !$omp& order(concurrent) !allocate (f) + do i = 1, 64 + ll = ll + 1 + end do + !$omp end taskgroup + + !$omp taskgroup task_reduction(+:r) !allocate (r) + !$omp taskloop simd & + !$omp& private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) & + !$omp& collapse(1) untied if(i1) final(fi) mergeable nogroup priority (pp) & + !$omp& safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) in_reduction(+:r) nontemporal(ntm) & + !$omp& order(concurrent) !allocate (f) + do i = 1, 64 + ll = ll + 1 + end do + !$omp taskwait + + !$omp taskloop simd & + !$omp& private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) & + !$omp& collapse(1) if(taskloop: i1) final(fi) priority (pp) & + !$omp& safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(+:r) if (simd: i3) nontemporal(ntm) & + !$omp& order(concurrent) !allocate (f) + do i = 1, 64 + ll = ll + 1 + end do + !$omp end taskgroup + + !$omp taskgroup task_reduction (+:r2) !allocate (r2) + !$omp master taskloop & + !$omp& private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) & + !$omp& collapse(1) untied if(taskloop: i1) final(fi) mergeable priority (pp) & + !$omp& reduction(default, +:r) in_reduction(+:r2) !allocate (f) + do i = 1, 64 + ll = ll + 1 + end do + !$omp end taskgroup + + !$omp taskgroup task_reduction (+:r2) !allocate (r2) + !$omp master taskloop simd & + !$omp& private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) & + !$omp& collapse(1) untied if(taskloop: i1) if(simd: i2) final(fi) mergeable priority (pp) & + !$omp& safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm) & + !$omp& order(concurrent) !allocate (f) + do i = 1, 64 + ll = ll + 1 + end do + !$omp end taskgroup + + !$omp parallel master taskloop & + !$omp& private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) & + !$omp& collapse(1) untied if(taskloop: i1) final(fi) mergeable priority (pp) & + !$omp& reduction(default, +:r) if (parallel: i2) num_threads (nth) proc_bind(spread) copyin(t) !allocate (f) + do i = 1, 64 + ll = ll + 1 + end do + + !$omp parallel master taskloop simd & + !$omp& private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) & + !$omp& untied if(taskloop: i1) if(simd: i2) final(fi) mergeable priority (pp) & + !$omp& safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) nontemporal(ntm) & + !$omp& if (parallel: i2) num_threads (nth) proc_bind(spread) copyin(t) & + !$omp& order(concurrent) !allocate (f) + do i = 1, 64 + ll = ll + 1 + end do + + !$omp taskgroup task_reduction (+:r2) !allocate (r2) + !$omp master taskloop & + !$omp& private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) & + !$omp& collapse(1) untied if(i1) final(fi) mergeable priority (pp) & + !$omp& reduction(default, +:r) in_reduction(+:r2) + do i = 1, 64 + ll = ll + 1 + end do + !$omp end taskgroup + + !$omp taskgroup task_reduction (+:r2) !allocate (r2) + !$omp master taskloop simd & + !$omp& private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) & + !$omp& collapse(1) untied if(i1) final(fi) mergeable priority (pp) & + !$omp& safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm) & + !$omp& order(concurrent) !allocate (f) + do i = 1, 64 + ll = ll + 1 + end do + !$omp end taskgroup + + !$omp parallel master taskloop & + !$omp& private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) & + !$omp& collapse(1) untied if(i1) final(fi) mergeable priority (pp) & + !$omp& reduction(default, +:r) num_threads (nth) proc_bind(spread) copyin(t) !allocate (f) + do i = 1, 64 + ll = ll + 1 + end do + + !$omp parallel master taskloop simd & + !$omp& private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) & + !$omp& collapse(1) untied if(i1) final(fi) mergeable priority (pp) & + !$omp& safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) & + !$omp& nontemporal(ntm) num_threads (nth) proc_bind(spread) copyin(t) & + !$omp& order(concurrent) !allocate (f) + do i = 1, 64 + ll = ll + 1 + end do +end