diff options
author | Jakub Jelinek <jakub@redhat.com> | 2022-09-03 09:41:54 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2022-09-03 10:04:00 +0200 |
commit | a651e6d59188da8992f8bfae2df1cb4e6316f9e6 (patch) | |
tree | ea5383dc6af17ad39a90f8bd40dae7f62d1547ae /gcc/cp/parser.cc | |
parent | c64b09471a8a06e929c70bf6017d7163776145e0 (diff) | |
download | gcc-a651e6d59188da8992f8bfae2df1cb4e6316f9e6.zip gcc-a651e6d59188da8992f8bfae2df1cb4e6316f9e6.tar.gz gcc-a651e6d59188da8992f8bfae2df1cb4e6316f9e6.tar.bz2 |
openmp: Partial OpenMP 5.2 doacross and omp_cur_iteration support
The following patch implements part of the OpenMP 5.2 changes related
to ordered loops and with the assumed resolution of
https://github.com/OpenMP/spec/issues/3302 issues.
The changes are:
1) the depend clause on stand-alone ordered constructs has been renamed
to doacross (because depend clause has different syntax on other
constructs) with some syntax changes below, depend clause is deprecated
(we'll deprecate stuff on the GCC side only when we have everything else
from 5.2 implemented)
depend(source) -> doacross(source:) or doacross(source:omp_cur_iteration)
depend(sink:vec) -> doacross(sink:vec) (where vec has the same syntax
as before)
2) in 5.1 and before it has been significant whether ordered clause has or
doesn't have an argument, if it didn't, only block-associated ordered
could appear in the body, if it did, only stand-alone ordered could appear
in the body, all loops had to be perfectly nested, no associated
range-based for loops, no linear clause on work-sharing loop and ordered
clause with an argument wasn't allowed on composite for simd.
In 5.2, whether ordered clause has or doesn't have an argument is
insignificant (except for bugs in the standard, #3302 mentions those),
if the argument is missing, it is simply treated as equal to collapse
argument (if any, otherwise 1). The implementation better should be able
to differentiate between ordered and doacross loops at compile time
which previously was through the absence or presence of the argument,
now it is done through looking at the body of the construct lexically
and looking for stand-alone ordered constructs. If there are any,
it is to be handled as doacross loop, otherwise it is ordered loop
(but in that case ordered argument if present must be equal to collapse
argument - 5.2 says instead it must be one, but that is clearly wrong
and mentioned in #3302) - stand-alone ordered constructs must appear
lexically in the body (and had to before as well). For the restrictions
mentioned above, the for simd restriction is gone (stand-alone ordered
can't appear in simd construct, so that is enough), and the other rules
are expected to be changed into something related to presence of
stand-alone ordered constructs in the body
3) 5.2 allows a new syntax, doacross(sink:omp_cur_iteration-1), which
means wait for previous iteration in the iteration space of all the
associated loops
The following patch implements that, except that we sorry for now
on the doacross(sink:omp_cur_iteration-1) syntax during omp expansion
because library side isn't done yet for it. It doesn't implement it for
the Fortran FE either.
Incrementally, I'd like to change the way we differentiate between
stand-alone and block-associated ordered constructs, because the current
way of looking for presence of doacross clause doesn't work well if those
clauses are removed because they had been invalid (wrong syntax or
unknown variables in it etc.) and of course implement
doacross(sink:omp_cur_iteration-1).
2022-09-03 Jakub Jelinek <jakub@redhat.com>
gcc/
* tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_DOACROSS.
(enum omp_clause_depend_kind): Remove OMP_CLAUSE_DEPEND_SOURCE
and OMP_CLAUSE_DEPEND_SINK, add OMP_CLAUSE_DEPEND_INVALID.
(enum omp_clause_doacross_kind): New type.
(struct tree_omp_clause): Add subcode.doacross_kind member.
* tree.h (OMP_CLAUSE_DEPEND_SINK_NEGATIVE): Remove.
(OMP_CLAUSE_DOACROSS_KIND): Define.
(OMP_CLAUSE_DOACROSS_SINK_NEGATIVE): Define.
(OMP_CLAUSE_DOACROSS_DEPEND): Define.
(OMP_CLAUSE_ORDERED_DOACROSS): Define.
* tree.cc (omp_clause_num_ops, omp_clause_code_name): Add
OMP_CLAUSE_DOACROSS entries.
* tree-nested.cc (convert_nonlocal_omp_clauses,
convert_local_omp_clauses): Handle OMP_CLAUSE_DOACROSS.
* tree-pretty-print.cc (dump_omp_clause): Don't handle
OMP_CLAUSE_DEPEND_SOURCE and OMP_CLAUSE_DEPEND_SINK. Handle
OMP_CLAUSE_DOACROSS.
* gimplify.cc (gimplify_omp_depend): Don't handle
OMP_CLAUSE_DEPEND_SOURCE and OMP_CLAUSE_DEPEND_SINK.
(gimplify_scan_omp_clauses): Likewise. Handle OMP_CLAUSE_DOACROSS.
(gimplify_adjust_omp_clauses): Handle OMP_CLAUSE_DOACROSS.
(find_standalone_omp_ordered): New function.
(gimplify_omp_for): When OMP_CLAUSE_ORDERED is present, search
body for OMP_ORDERED with OMP_CLAUSE_DOACROSS and if found,
set OMP_CLAUSE_ORDERED_DOACROSS.
(gimplify_omp_ordered): Don't handle OMP_CLAUSE_DEPEND_SINK or
OMP_CLAUSE_DEPEND_SOURCE, instead check OMP_CLAUSE_DOACROSS, adjust
diagnostics that presence or absence of ordered clause parameter
is irrelevant. Handle doacross(sink:omp_cur_iteration-1). Use
actual user name of the clause - doacross or depend - in diagnostics.
* omp-general.cc (omp_extract_for_data): Don't set fd->ordered
if !OMP_CLAUSE_ORDERED_DOACROSS (t). If
OMP_CLAUSE_ORDERED_DOACROSS (t) but !OMP_CLAUSE_ORDERED_EXPR (t),
set fd->ordered to -1 and set it after the loop in that case to
fd->collapse.
* omp-low.cc (check_omp_nesting_restrictions): Don't handle
OMP_CLAUSE_DEPEND_SOURCE nor OMP_CLAUSE_DEPEND_SINK, instead check
OMP_CLAUSE_DOACROSS. Use actual user name of the clause - doacross
or depend - in diagnostics. Diagnose mixing of stand-alone and
block associated ordered constructs binding to the same loop.
(lower_omp_ordered_clauses): Don't handle OMP_CLAUSE_DEPEND_SINK,
instead handle OMP_CLAUSE_DOACROSS.
(lower_omp_ordered): Look for OMP_CLAUSE_DOACROSS instead of
OMP_CLAUSE_DEPEND.
(lower_depend_clauses): Don't handle OMP_CLAUSE_DEPEND_SOURCE and
OMP_CLAUSE_DEPEND_SINK.
* omp-expand.cc (expand_omp_ordered_sink): Emit a sorry for
doacross(sink:omp_cur_iteration-1).
(expand_omp_ordered_source_sink): Use
OMP_CLAUSE_DOACROSS_SINK_NEGATIVE instead of
OMP_CLAUSE_DEPEND_SINK_NEGATIVE. Use actual user name of the clause
- doacross or depend - in diagnostics.
(expand_omp): Look for OMP_CLAUSE_DOACROSS clause instead of
OMP_CLAUSE_DEPEND.
(build_omp_regions_1): Likewise.
(omp_make_gimple_edges): Likewise.
* lto-streamer-out.cc (hash_tree): Handle OMP_CLAUSE_DOACROSS.
* tree-streamer-in.cc (unpack_ts_omp_clause_value_fields): Likewise.
* tree-streamer-out.cc (pack_ts_omp_clause_value_fields): Likewise.
gcc/c-family/
* c-pragma.h (enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_DOACROSS.
* c-omp.cc (c_finish_omp_depobj): Check also for OMP_CLAUSE_DOACROSS
clause and diagnose it. Don't handle OMP_CLAUSE_DEPEND_SOURCE and
OMP_CLAUSE_DEPEND_SINK. Assert kind is not OMP_CLAUSE_DEPEND_INVALID.
gcc/c/
* c-parser.cc (c_parser_omp_clause_name): Handle doacross.
(c_parser_omp_clause_depend_sink): Renamed to ...
(c_parser_omp_clause_doacross_sink): ... this. Add depend_p argument.
Handle parsing of doacross(sink:omp_cur_iteration-1). Use
OMP_CLAUSE_DOACROSS_SINK_NEGATIVE instead of
OMP_CLAUSE_DEPEND_SINK_NEGATIVE, build OMP_CLAUSE_DOACROSS instead
of OMP_CLAUSE_DEPEND and set OMP_CLAUSE_DOACROSS_DEPEND flag on it.
(c_parser_omp_clause_depend): Use OMP_CLAUSE_DOACROSS_SINK and
OMP_CLAUSE_DOACROSS_SOURCE instead of OMP_CLAUSE_DEPEND_SINK and
OMP_CLAUSE_DEPEND_SOURCE, build OMP_CLAUSE_DOACROSS for depend(source)
and set OMP_CLAUSE_DOACROSS_DEPEND on it.
(c_parser_omp_clause_doacross): New function.
(c_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_DOACROSS.
(c_parser_omp_depobj): Use OMP_CLAUSE_DEPEND_INVALID instead of
OMP_CLAUSE_DEPEND_SOURCE.
(c_parser_omp_for_loop): Don't diagnose here linear clause together
with ordered with argument.
(c_parser_omp_simd): Don't diagnose ordered clause with argument on
for simd.
(OMP_ORDERED_DEPEND_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_DOACROSS.
(c_parser_omp_ordered): Handle also doacross and adjust for it
diagnostic wording.
* c-typeck.cc (c_finish_omp_clauses): Handle OMP_CLAUSE_DOACROSS.
Don't handle OMP_CLAUSE_DEPEND_SOURCE and OMP_CLAUSE_DEPEND_SINK.
gcc/cp/
* parser.cc (cp_parser_omp_clause_name): Handle doacross.
(cp_parser_omp_clause_depend_sink): Renamed to ...
(cp_parser_omp_clause_doacross_sink): ... this. Add depend_p
argument. Handle parsing of doacross(sink:omp_cur_iteration-1). Use
OMP_CLAUSE_DOACROSS_SINK_NEGATIVE instead of
OMP_CLAUSE_DEPEND_SINK_NEGATIVE, build OMP_CLAUSE_DOACROSS instead
of OMP_CLAUSE_DEPEND and set OMP_CLAUSE_DOACROSS_DEPEND flag on it.
(cp_parser_omp_clause_depend): Use OMP_CLAUSE_DOACROSS_SINK and
OMP_CLAUSE_DOACROSS_SOURCE instead of OMP_CLAUSE_DEPEND_SINK and
OMP_CLAUSE_DEPEND_SOURCE, build OMP_CLAUSE_DOACROSS for depend(source)
and set OMP_CLAUSE_DOACROSS_DEPEND on it.
(cp_parser_omp_clause_doacross): New function.
(cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_DOACROSS.
(cp_parser_omp_depobj): Use OMP_CLAUSE_DEPEND_INVALID instead of
OMP_CLAUSE_DEPEND_SOURCE.
(cp_parser_omp_for_loop): Don't diagnose here linear clause together
with ordered with argument.
(cp_parser_omp_simd): Don't diagnose ordered clause with argument on
for simd.
(OMP_ORDERED_DEPEND_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_DOACROSS.
(cp_parser_omp_ordered): Handle also doacross and adjust for it
diagnostic wording.
* pt.cc (tsubst_omp_clause_decl): Use
OMP_CLAUSE_DOACROSS_SINK_NEGATIVE instead of
OMP_CLAUSE_DEPEND_SINK_NEGATIVE.
(tsubst_omp_clauses): Handle OMP_CLAUSE_DOACROSS.
(tsubst_expr): Use OMP_CLAUSE_DEPEND_INVALID instead of
OMP_CLAUSE_DEPEND_SOURCE.
* semantics.cc (cp_finish_omp_clause_depend_sink): Rename to ...
(cp_finish_omp_clause_doacross_sink): ... this.
(finish_omp_clauses): Handle OMP_CLAUSE_DOACROSS. Don't handle
OMP_CLAUSE_DEPEND_SOURCE and OMP_CLAUSE_DEPEND_SINK.
gcc/fortran/
* trans-openmp.cc (gfc_trans_omp_clauses): Use
OMP_CLAUSE_DOACROSS_SINK_NEGATIVE instead of
OMP_CLAUSE_DEPEND_SINK_NEGATIVE, build OMP_CLAUSE_DOACROSS
clause instead of OMP_CLAUSE_DEPEND and set OMP_CLAUSE_DOACROSS_DEPEND
on it.
gcc/testsuite/
* c-c++-common/gomp/doacross-2.c: Adjust expected diagnostics.
* c-c++-common/gomp/doacross-5.c: New test.
* c-c++-common/gomp/doacross-6.c: New test.
* c-c++-common/gomp/nesting-2.c: Adjust expected diagnostics.
* c-c++-common/gomp/ordered-3.c: Likewise.
* c-c++-common/gomp/sink-3.c: Likewise.
* gfortran.dg/gomp/nesting-2.f90: Likewise.
Diffstat (limited to 'gcc/cp/parser.cc')
-rw-r--r-- | gcc/cp/parser.cc | 178 |
1 files changed, 131 insertions, 47 deletions
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 13435d2..076ad62 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -11994,14 +11994,18 @@ cp_parser_handle_statement_omp_attributes (cp_parser *parser, tree attrs) if (dir->id == PRAGMA_OMP_ORDERED) { /* ordered is C_OMP_DIR_CONSTRUCT only if it doesn't contain - depend clause. */ - if (directive[1] && strcmp (directive[1], "depend") == 0) + depend/doacross clause. */ + if (directive[1] + && (strcmp (directive[1], "depend") == 0 + || strcmp (directive[1], "doacross") == 0)) kind = C_OMP_DIR_STANDALONE; else if (first + 2 < last && first[1].type == CPP_COMMA && first[2].type == CPP_NAME - && strcmp (IDENTIFIER_POINTER (first[2].u.value), - "depend") == 0) + && (strcmp (IDENTIFIER_POINTER (first[2].u.value), + "depend") == 0 + || strcmp (IDENTIFIER_POINTER (first[2].u.value), + "doacross") == 0)) kind = C_OMP_DIR_STANDALONE; } else if (dir->id == PRAGMA_OMP_ERROR) @@ -36602,6 +36606,8 @@ cp_parser_omp_clause_name (cp_parser *parser) result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE; else if (!strcmp ("dist_schedule", p)) result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE; + else if (!strcmp ("doacross", p)) + result = PRAGMA_OMP_CLAUSE_DOACROSS; break; case 'e': if (!strcmp ("enter", p)) @@ -39329,8 +39335,8 @@ cp_parser_omp_clause_simdlen (cp_parser *parser, tree list, */ static tree -cp_parser_omp_clause_depend_sink (cp_parser *parser, location_t clause_loc, - tree list) +cp_parser_omp_clause_doacross_sink (cp_parser *parser, location_t clause_loc, + tree list, bool depend_p) { tree vec = NULL; @@ -39340,6 +39346,29 @@ cp_parser_omp_clause_depend_sink (cp_parser *parser, location_t clause_loc, return list; } + if (!depend_p) + { + tree id = cp_lexer_peek_token (parser->lexer)->u.value; + if (strcmp (IDENTIFIER_POINTER (id), "omp_cur_iteration") == 0 + && cp_lexer_nth_token_is (parser->lexer, 2, CPP_MINUS) + && cp_lexer_nth_token_is (parser->lexer, 3, CPP_NUMBER) + && cp_lexer_nth_token_is (parser->lexer, 4, CPP_CLOSE_PAREN)) + { + tree val = cp_lexer_peek_nth_token (parser->lexer, 3)->u.value; + if (integer_onep (val) + && same_type_p (TREE_TYPE (val), integer_type_node)) + { + cp_lexer_consume_token (parser->lexer); + cp_lexer_consume_token (parser->lexer); + cp_lexer_consume_token (parser->lexer); + tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS); + OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK; + OMP_CLAUSE_CHAIN (u) = list; + return u; + } + } + } + while (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) { location_t id_loc = cp_lexer_peek_token (parser->lexer)->location; @@ -39387,7 +39416,7 @@ cp_parser_omp_clause_depend_sink (cp_parser *parser, location_t clause_loc, { vec = tree_cons (addend, t, vec); if (neg) - OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1; + OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec) = 1; } if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA) @@ -39399,8 +39428,9 @@ cp_parser_omp_clause_depend_sink (cp_parser *parser, location_t clause_loc, if (vec) { - tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND); - OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK; + tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS); + OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK; + OMP_CLAUSE_DOACROSS_DEPEND (u) = depend_p; OMP_CLAUSE_DECL (u) = nreverse (vec); OMP_CLAUSE_CHAIN (u) = list; return u; @@ -39649,6 +39679,7 @@ cp_parser_omp_clause_depend (cp_parser *parser, tree list, location_t loc) { tree nlist, c, iterators = NULL_TREE; enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST; + enum omp_clause_doacross_kind dkind = OMP_CLAUSE_DOACROSS_LAST; matching_parens parens; if (!parens.require_open (parser)) @@ -39682,9 +39713,9 @@ cp_parser_omp_clause_depend (cp_parser *parser, tree list, location_t loc) else if (strcmp ("depobj", p) == 0) kind = OMP_CLAUSE_DEPEND_DEPOBJ; else if (strcmp ("sink", p) == 0) - kind = OMP_CLAUSE_DEPEND_SINK; + dkind = OMP_CLAUSE_DOACROSS_SINK; else if (strcmp ("source", p) == 0) - kind = OMP_CLAUSE_DEPEND_SOURCE; + dkind = OMP_CLAUSE_DOACROSS_SOURCE; else goto invalid_kind; break; @@ -39694,18 +39725,20 @@ cp_parser_omp_clause_depend (cp_parser *parser, tree list, location_t loc) cp_lexer_consume_token (parser->lexer); if (iterators - && (kind == OMP_CLAUSE_DEPEND_SOURCE || kind == OMP_CLAUSE_DEPEND_SINK)) + && (dkind == OMP_CLAUSE_DOACROSS_SOURCE + || dkind == OMP_CLAUSE_DOACROSS_SINK)) { poplevel (0, 1, 0); error_at (loc, "%<iterator%> modifier incompatible with %qs", - kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink"); + dkind == OMP_CLAUSE_DOACROSS_SOURCE ? "source" : "sink"); iterators = NULL_TREE; } - if (kind == OMP_CLAUSE_DEPEND_SOURCE) + if (dkind == OMP_CLAUSE_DOACROSS_SOURCE) { - c = build_omp_clause (loc, OMP_CLAUSE_DEPEND); - OMP_CLAUSE_DEPEND_KIND (c) = kind; + c = build_omp_clause (loc, OMP_CLAUSE_DOACROSS); + OMP_CLAUSE_DOACROSS_KIND (c) = dkind; + OMP_CLAUSE_DOACROSS_DEPEND (c) = 1; OMP_CLAUSE_DECL (c) = NULL_TREE; OMP_CLAUSE_CHAIN (c) = list; if (!parens.require_close (parser)) @@ -39718,9 +39751,9 @@ cp_parser_omp_clause_depend (cp_parser *parser, tree list, location_t loc) if (!cp_parser_require (parser, CPP_COLON, RT_COLON)) goto resync_fail; - if (kind == OMP_CLAUSE_DEPEND_SINK) + if (dkind == OMP_CLAUSE_DOACROSS_SINK) { - nlist = cp_parser_omp_clause_depend_sink (parser, loc, list); + nlist = cp_parser_omp_clause_doacross_sink (parser, loc, list, true); if (!parens.require_close (parser)) cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, /*or_comma=*/false, @@ -39761,6 +39794,73 @@ cp_parser_omp_clause_depend (cp_parser *parser, tree list, location_t loc) return list; } +/* OpenMP 5.2: + doacross ( source : ) + doacross ( source : omp_cur_iteration ) + + doacross ( sink : vec ) + doacross ( sink : omp_cur_iteration - logical_iteration ) */ + +static tree +cp_parser_omp_clause_doacross (cp_parser *parser, tree list, location_t loc) +{ + tree nlist; + enum omp_clause_doacross_kind kind = OMP_CLAUSE_DOACROSS_LAST; + + matching_parens parens; + if (!parens.require_open (parser)) + return list; + + if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)) + { + invalid_kind: + cp_parser_error (parser, "invalid doacross kind"); + resync_fail: + cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/true); + return list; + } + + tree id = cp_lexer_peek_token (parser->lexer)->u.value; + const char *p = IDENTIFIER_POINTER (id); + + if (strcmp ("sink", p) == 0) + kind = OMP_CLAUSE_DOACROSS_SINK; + else if (strcmp ("source", p) == 0) + kind = OMP_CLAUSE_DOACROSS_SOURCE; + else + goto invalid_kind; + + cp_lexer_consume_token (parser->lexer); + + if (!cp_parser_require (parser, CPP_COLON, RT_COLON)) + goto resync_fail; + + if (kind == OMP_CLAUSE_DOACROSS_SOURCE) + { + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) + { + id = cp_lexer_peek_token (parser->lexer)->u.value; + p = IDENTIFIER_POINTER (id); + if (strcmp (p, "omp_cur_iteration") == 0) + cp_lexer_consume_token (parser->lexer); + } + nlist = build_omp_clause (loc, OMP_CLAUSE_DOACROSS); + OMP_CLAUSE_DOACROSS_KIND (nlist) = OMP_CLAUSE_DOACROSS_SOURCE; + OMP_CLAUSE_DECL (nlist) = NULL_TREE; + OMP_CLAUSE_CHAIN (nlist) = list; + } + else + nlist = cp_parser_omp_clause_doacross_sink (parser, loc, list, false); + + if (!parens.require_close (parser)) + cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/true); + return nlist; +} + /* OpenMP 4.0: map ( map-kind : variable-list ) map ( variable-list ) @@ -40703,6 +40803,11 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask, token->location); c_name = "depend"; break; + case PRAGMA_OMP_CLAUSE_DOACROSS: + clauses = cp_parser_omp_clause_doacross (parser, clauses, + token->location); + c_name = "doacross"; + break; case PRAGMA_OMP_CLAUSE_DETACH: clauses = cp_parser_omp_clause_detach (parser, clauses); c_name = "detach"; @@ -41941,7 +42046,7 @@ cp_parser_omp_depobj (cp_parser *parser, cp_token *pragma_tok) /*consume_paren=*/true); tree clause = NULL_TREE; - enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_SOURCE; + enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INVALID; location_t c_loc = cp_lexer_peek_token (parser->lexer)->location; /* For now only in C++ attributes, do it always for OpenMP 5.1. */ if (parser->lexer->in_omp_attribute_pragma @@ -41989,7 +42094,7 @@ cp_parser_omp_depobj (cp_parser *parser, cp_token *pragma_tok) else if (!strcmp ("inoutset", p2)) kind = OMP_CLAUSE_DEPEND_INOUTSET; } - if (kind == OMP_CLAUSE_DEPEND_SOURCE) + if (kind == OMP_CLAUSE_DEPEND_INVALID) { clause = error_mark_node; error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%>, " @@ -42005,7 +42110,7 @@ cp_parser_omp_depobj (cp_parser *parser, cp_token *pragma_tok) clause = error_mark_node; } } - if (!clause && kind == OMP_CLAUSE_DEPEND_SOURCE) + if (!clause && kind == OMP_CLAUSE_DEPEND_INVALID) { clause = error_mark_node; error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause"); @@ -42837,19 +42942,6 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses, = build_int_cst (NULL_TREE, collapse); ordered = collapse; } - if (ordered) - { - for (tree *pc = &clauses; *pc; ) - if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR) - { - error_at (OMP_CLAUSE_LOCATION (*pc), - "%<linear%> clause may not be specified together " - "with %<ordered%> clause with a parameter"); - *pc = OMP_CLAUSE_CHAIN (*pc); - } - else - pc = &OMP_CLAUSE_CHAIN (*pc); - } gcc_assert (tiling || (collapse >= 1 && ordered >= 0)); count = ordered ? ordered : collapse; @@ -43301,15 +43393,6 @@ cp_parser_omp_simd (cp_parser *parser, cp_token *pragma_tok, { cp_omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses); clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD]; - tree c = omp_find_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR], - OMP_CLAUSE_ORDERED); - if (c && OMP_CLAUSE_ORDERED_EXPR (c)) - { - error_at (OMP_CLAUSE_LOCATION (c), - "%<ordered%> clause with parameter may not be specified " - "on %qs construct", p_name); - OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE; - } } keep_next_level (true); @@ -43571,7 +43654,8 @@ cp_parser_omp_masked (cp_parser *parser, cp_token *pragma_tok, | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD)) #define OMP_ORDERED_DEPEND_CLAUSE_MASK \ - (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DOACROSS)) static bool cp_parser_omp_ordered (cp_parser *parser, cp_token *pragma_tok, @@ -43590,7 +43674,7 @@ cp_parser_omp_ordered (cp_parser *parser, cp_token *pragma_tok, tree id = cp_lexer_peek_nth_token (parser->lexer, n)->u.value; const char *p = IDENTIFIER_POINTER (id); - if (strcmp (p, "depend") == 0) + if (strcmp (p, "depend") == 0 || strcmp (p, "doacross") == 0) { if (!flag_openmp) /* flag_openmp_simd */ { @@ -43600,8 +43684,8 @@ cp_parser_omp_ordered (cp_parser *parser, cp_token *pragma_tok, if (context == pragma_stmt) { error_at (pragma_tok->location, "%<#pragma omp ordered%> with " - "%<depend%> clause may only be used in compound " - "statements"); + "%qs clause may only be used in compound " + "statements", p); cp_parser_skip_to_pragma_eol (parser, pragma_tok); return true; } |