aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-openmp.cc
diff options
context:
space:
mode:
authorTobias Burnus <tobias@codesourcery.com>2023-04-25 16:29:14 +0200
committerTobias Burnus <tobias@codesourcery.com>2023-04-25 16:29:14 +0200
commit1c101fcfaac8f609d618f83b124bd50aea012132 (patch)
treedd1ac83cab1561d60c15f2083fcc243b452636a8 /gcc/fortran/trans-openmp.cc
parent78aaaf862e70cea45f3a2be7cb855cfe1a4ead21 (diff)
downloadgcc-1c101fcfaac8f609d618f83b124bd50aea012132.zip
gcc-1c101fcfaac8f609d618f83b124bd50aea012132.tar.gz
gcc-1c101fcfaac8f609d618f83b124bd50aea012132.tar.bz2
'omp scan' struct block seq update for OpenMP 5.x
While OpenMP 5.0 required a single structured block before and after the 'omp scan' directive, OpenMP 5.1 changed this to a 'structured block sequence, denoting 2 or more executable statements in OpenMP 5.1 (whoops!) and zero or more in OpenMP 5.2. This commit updates C/C++ to accept zero statements (but till requires the '{' ... '}' for the final-loop-body) and updates Fortran to accept zero or more than one statements. If there is no preceeding or succeeding executable statement, a warning is shown. gcc/c/ChangeLog: * c-parser.cc (c_parser_omp_scan_loop_body): Handle zero exec statements before/after 'omp scan'. gcc/cp/ChangeLog: * parser.cc (cp_parser_omp_scan_loop_body): Handle zero exec statements before/after 'omp scan'. gcc/fortran/ChangeLog: * openmp.cc (gfc_resolve_omp_do_blocks): Handle zero or more than one exec statements before/after 'omp scan'. * trans-openmp.cc (gfc_trans_omp_do): Likewise. libgomp/ChangeLog: * testsuite/libgomp.c-c++-common/scan-1.c: New test. * testsuite/libgomp.c/scan-23.c: New test. * testsuite/libgomp.fortran/scan-2.f90: New test. gcc/testsuite/ChangeLog: * g++.dg/gomp/attrs-7.C: Update dg-error/dg-warning. * gfortran.dg/gomp/loop-2.f90: Likewise. * gfortran.dg/gomp/reduction5.f90: Likewise. * gfortran.dg/gomp/reduction6.f90: Likewise. * gfortran.dg/gomp/scan-1.f90: Likewise. * gfortran.dg/gomp/taskloop-2.f90: Likewise. * c-c++-common/gomp/scan-6.c: New test. * gfortran.dg/gomp/scan-8.f90: New test.
Diffstat (limited to 'gcc/fortran/trans-openmp.cc')
-rw-r--r--gcc/fortran/trans-openmp.cc31
1 files changed, 17 insertions, 14 deletions
diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index 84c0184..4ff9c59 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -5603,26 +5603,29 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock,
/* Main loop body. */
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);
+ gfc_code *code1, *scan, *code2, *tmpcode;
+ code1 = tmpcode = code->block->next;
+ if (tmpcode && tmpcode->op != EXEC_OMP_SCAN)
+ while (tmpcode && tmpcode->next && tmpcode->next->op != EXEC_OMP_SCAN)
+ tmpcode = tmpcode->next;
+ scan = tmpcode->op == EXEC_OMP_SCAN ? tmpcode : tmpcode->next;
+ if (code1 != scan)
+ tmpcode->next = NULL;
+ code2 = scan->next;
+ gcc_assert (scan->op == EXEC_OMP_SCAN);
+ location_t loc = gfc_get_location (&scan->loc);
+
+ tmp = code1 != scan ? gfc_trans_code (code1) : build_empty_stmt (loc);
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);
+ tree c = gfc_trans_omp_clauses (&body, scan->ext.omp_clauses, scan->loc);
+ tmp = code2 ? gfc_trans_code (code2) : build_empty_stmt (loc);
tmp = build2 (OMP_SCAN, void_type_node, tmp, c);
SET_EXPR_LOCATION (tmp, loc);
+ if (code1 != scan)
+ tmpcode->next = scan;
}
else
tmp = gfc_trans_omp_code (code->block->next, true);