diff options
author | Tobias Burnus <tobias@codesourcery.com> | 2020-12-08 16:49:46 +0100 |
---|---|---|
committer | Tobias Burnus <tobias@codesourcery.com> | 2020-12-08 16:54:22 +0100 |
commit | 005cff4e2ecbd5c4e2ef978fe4842fa3c8c79f47 (patch) | |
tree | fd67e840cf2cc4a475ce8a08dd25ed9cdf595d5a /gcc/fortran/trans-openmp.c | |
parent | e401db7bfd8cf86d3833805a81b1252884eb1c9d (diff) | |
download | gcc-005cff4e2ecbd5c4e2ef978fe4842fa3c8c79f47.zip gcc-005cff4e2ecbd5c4e2ef978fe4842fa3c8c79f47.tar.gz gcc-005cff4e2ecbd5c4e2ef978fe4842fa3c8c79f47.tar.bz2 |
Fortran: Add 'omp scan' support of OpenMP 5.0
gcc/fortran/ChangeLog:
* dump-parse-tree.c (show_omp_clauses, show_omp_node,
show_code_node): Handle OMP SCAN.
* gfortran.h (enum gfc_statement): Add ST_OMP_SCAN.
(enum): Add OMP_LIST_SCAN_IN and OMP_LIST_SCAN_EX.
(enum gfc_exec_op): Add EXEC_OMP_SCAN.
* match.h (gfc_match_omp_scan): New prototype.
* openmp.c (gfc_match_omp_scan): New.
(gfc_match_omp_taskgroup): Cleanup.
(resolve_omp_clauses, gfc_resolve_omp_do_blocks,
omp_code_to_statement, gfc_resolve_omp_directive): Handle 'omp scan'.
* parse.c (decode_omp_directive, next_statement,
gfc_ascii_statement): Likewise.
* resolve.c (gfc_resolve_code): Handle EXEC_OMP_SCAN.
* st.c (gfc_free_statement): Likewise.
* trans-openmp.c (gfc_trans_omp_clauses, gfc_trans_omp_do,
gfc_split_omp_clauses): Handle 'omp scan'.
libgomp/ChangeLog:
* testsuite/libgomp.fortran/scan-1.f90: New test.
gcc/testsuite/ChangeLog:
* gfortran.dg/gomp/reduction4.f90: Update; move FE some tests to ...
* gfortran.dg/gomp/reduction6.f90: ... this new test and ...
* gfortran.dg/gomp/reduction7.f90: ... this new test.
* gfortran.dg/gomp/reduction5.f90: Add dg-error.
* gfortran.dg/gomp/scan-1.f90: New test.
* gfortran.dg/gomp/scan-2.f90: New test.
* gfortran.dg/gomp/scan-3.f90: New test.
* gfortran.dg/gomp/scan-4.f90: New test.
* gfortran.dg/gomp/scan-5.f90: New test.
* gfortran.dg/gomp/scan-6.f90: New test.
* gfortran.dg/gomp/scan-7.f90: New test.
Diffstat (limited to 'gcc/fortran/trans-openmp.c')
-rw-r--r-- | gcc/fortran/trans-openmp.c | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index 6b4ad6a..ae29064 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -2334,6 +2334,12 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, case OMP_LIST_NONTEMPORAL: clause_code = OMP_CLAUSE_NONTEMPORAL; goto add_clause; + case OMP_LIST_SCAN_IN: + clause_code = OMP_CLAUSE_INCLUSIVE; + goto add_clause; + case OMP_LIST_SCAN_EX: + clause_code = OMP_CLAUSE_EXCLUSIVE; + goto add_clause; add_clause: omp_clauses @@ -4707,7 +4713,31 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock, code->exit_label = NULL_TREE; /* Main loop body. */ - tmp = gfc_trans_omp_code (code->block->next, true); + if (clauses->lists[OMP_LIST_REDUCTION_INSCAN]) + { + gcc_assert (code->block->next->next->op == EXEC_OMP_SCAN); + gcc_assert (code->block->next->next->next->next == NULL); + locus *cloc = &code->block->next->next->loc; + location_t loc = gfc_get_location (cloc); + + gfc_code code2 = *code->block->next; + code2.next = NULL; + tmp = gfc_trans_code (&code2); + tmp = build2 (OMP_SCAN, void_type_node, tmp, NULL_TREE); + SET_EXPR_LOCATION (tmp, loc); + gfc_add_expr_to_block (&body, tmp); + input_location = loc; + tree c = gfc_trans_omp_clauses (&body, + code->block->next->next->ext.omp_clauses, + *cloc); + code2 = *code->block->next->next->next; + code2.next = NULL; + tmp = gfc_trans_code (&code2); + tmp = build2 (OMP_SCAN, void_type_node, tmp, c); + SET_EXPR_LOCATION (tmp, loc); + } + else + tmp = gfc_trans_omp_code (code->block->next, true); gfc_add_expr_to_block (&body, tmp); /* Label for cycle statements (if needed). */ @@ -5234,13 +5264,15 @@ gfc_split_omp_clauses (gfc_code *code, = code->ext.omp_clauses->lists[OMP_LIST_LASTPRIVATE]; /* Reduction is allowed on simd, do, parallel and teams. Duplicate it on all of them, but omit on do if - parallel is present. */ + parallel is present; additionally, inscan applies to do/simd only. */ for (int i = OMP_LIST_REDUCTION; i <= OMP_LIST_REDUCTION_TASK; i++) { - if (mask & GFC_OMP_MASK_TEAMS) + if (mask & GFC_OMP_MASK_TEAMS + && i != OMP_LIST_REDUCTION_INSCAN) clausesa[GFC_OMP_SPLIT_TEAMS].lists[i] = code->ext.omp_clauses->lists[i]; - if (mask & GFC_OMP_MASK_PARALLEL) + if (mask & GFC_OMP_MASK_PARALLEL + && i != OMP_LIST_REDUCTION_INSCAN) clausesa[GFC_OMP_SPLIT_PARALLEL].lists[i] = code->ext.omp_clauses->lists[i]; else if (mask & GFC_OMP_MASK_DO) |