aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2022-06-07 10:05:08 +0200
committerJakub Jelinek <jakub@redhat.com>2022-06-07 10:05:08 +0200
commit03b71406323ddc065b1d7837d8b43b17e4b048b5 (patch)
tree5bcbe506924a87854f78855d460f540622c920b1 /gcc/c
parent6bb0776e104b5ca5a7bed9f333a9690174b4d00b (diff)
downloadgcc-03b71406323ddc065b1d7837d8b43b17e4b048b5.zip
gcc-03b71406323ddc065b1d7837d8b43b17e4b048b5.tar.gz
gcc-03b71406323ddc065b1d7837d8b43b17e4b048b5.tar.bz2
openmp: Add support for OpenMP 5.2 linear clause syntax for C/C++
The syntax for linear clause changed in 5.2, the original syntax which is still valid is: linear (var1, var2) linear (var3, var4 : step1) The 4.5 syntax with modifiers like: linear (val (var5, var6)) linear (val (var7, var8) : step2) is still supported in 5.2, but is deprecated there. Instead, one can use a new syntax: linear (var9, var10 : val) linear (var11, var12 : step (step3), val) As val, ref, uval or step (someexpr) can be valid expressions (and especially in C++ can be const / constexpr / consteval), the spec says that when the whole step expression is val (or ref or uval) or step ( ... ) then it is the new modifier syntax, one can use + 0 or 0 + or 1 * or * 1 or ()s to say it is the old step expression. Also, 5.2 now allows val modifier to be specified even outside of declare simd (but not the other modifiers). I've implemented this for the new modifier syntax only, the old one keeps the old restriction (which is why OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER flag has been introduced). 2022-06-07 Jakub Jelinek <jakub@redhat.com> gcc/ * tree.h (OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER): Define. * tree-pretty-print.cc (dump_omp_clause) <case OMP_CLAUSE_LINEAR>: Adjust clause printing style depending on OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER. gcc/c/ * c-parser.cc (c_parser_omp_clause_linear): Parse OpenMP 5.2 style linear clause modifiers. Set OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER flag on the clauses when old style modifiers are used. * c-typeck.cc (c_finish_omp_clauses): Only reject linear clause with val modifier on simd or for if the old style modifiers are used. gcc/cp/ * parser.cc (cp_parser_omp_clause_linear): Parse OpenMP 5.2 style linear clause modifiers. Set OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER flag on the clauses when old style modifiers are used. * semantics.cc (finish_omp_clauses): Only reject linear clause with val modifier on simd or for if the old style modifiers are used. gcc/fortran/ * trans-openmp.cc (gfc_trans_omp_clauses): Set OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER on OMP_CLAUSE_LINEAR clauses unconditionally for now. gcc/testsuite/ * c-c++-common/gomp/linear-2.c: New test. * c-c++-common/gomp/linear-3.c: New test. * g++.dg/gomp/linear-3.C: New test. * g++.dg/gomp/linear-4.C: New test. * g++.dg/gomp/linear-5.C: New test.
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/c-parser.cc111
-rw-r--r--gcc/c/c-typeck.cc6
2 files changed, 106 insertions, 11 deletions
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index c9a8d14..1704a52 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -15668,7 +15668,17 @@ c_parser_omp_clause_allocate (c_parser *parser, tree list)
OpenMP 4.5:
linear ( modifier ( variable-list ) )
- linear ( modifier ( variable-list ) : expression ) */
+ linear ( modifier ( variable-list ) : expression )
+
+ modifier:
+ val
+
+ OpenMP 5.2:
+ linear ( variable-list : modifiers-list )
+
+ modifiers:
+ val
+ step ( expression ) */
static tree
c_parser_omp_clause_linear (c_parser *parser, tree list)
@@ -15676,6 +15686,7 @@ c_parser_omp_clause_linear (c_parser *parser, tree list)
location_t clause_loc = c_parser_peek_token (parser)->location;
tree nl, c, step;
enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
+ bool old_linear_modifier = false;
matching_parens parens;
if (!parens.require_open (parser))
@@ -15691,6 +15702,7 @@ c_parser_omp_clause_linear (c_parser *parser, tree list)
kind = OMP_CLAUSE_LINEAR_DEFAULT;
if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
{
+ old_linear_modifier = true;
c_parser_consume_token (parser);
c_parser_consume_token (parser);
}
@@ -15706,15 +15718,95 @@ c_parser_omp_clause_linear (c_parser *parser, tree list)
{
c_parser_consume_token (parser);
location_t expr_loc = c_parser_peek_token (parser)->location;
- c_expr expr = c_parser_expr_no_commas (parser, NULL);
- expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
- step = expr.value;
- step = c_fully_fold (step, false, NULL);
- if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
+ bool has_modifiers = false;
+ if (kind == OMP_CLAUSE_LINEAR_DEFAULT
+ && c_parser_next_token_is (parser, CPP_NAME))
+ {
+ c_token *tok = c_parser_peek_token (parser);
+ const char *p = IDENTIFIER_POINTER (tok->value);
+ unsigned int pos = 0;
+ if (strcmp ("val", p) == 0)
+ pos = 2;
+ else if (strcmp ("step", p) == 0
+ && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
+ {
+ pos = 3;
+ if (c_parser_check_balanced_raw_token_sequence (parser, &pos)
+ && (c_parser_peek_nth_token_raw (parser, pos)->type
+ == CPP_CLOSE_PAREN))
+ ++pos;
+ else
+ pos = 0;
+ }
+ if (pos)
+ {
+ tok = c_parser_peek_nth_token_raw (parser, pos);
+ if (tok->type == CPP_COMMA || tok->type == CPP_CLOSE_PAREN)
+ has_modifiers = true;
+ }
+ }
+ if (has_modifiers)
+ {
+ step = NULL_TREE;
+ while (c_parser_next_token_is (parser, CPP_NAME))
+ {
+ c_token *tok = c_parser_peek_token (parser);
+ const char *p = IDENTIFIER_POINTER (tok->value);
+ if (strcmp ("val", p) == 0)
+ {
+ if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
+ error_at (tok->location, "multiple linear modifiers");
+ kind = OMP_CLAUSE_LINEAR_DEFAULT;
+ c_parser_consume_token (parser);
+ }
+ else if (strcmp ("step", p) == 0)
+ {
+ c_parser_consume_token (parser);
+ matching_parens parens2;
+ if (parens2.require_open (parser))
+ {
+ if (step)
+ error_at (tok->location,
+ "multiple %<step%> modifiers");
+ expr_loc = c_parser_peek_token (parser)->location;
+ c_expr expr = c_parser_expr_no_commas (parser, NULL);
+ expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
+ true);
+ step = c_fully_fold (expr.value, false, NULL);
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
+ {
+ error_at (clause_loc, "%<linear%> clause step "
+ "expression must be integral");
+ step = integer_one_node;
+ }
+ parens2.skip_until_found_close (parser);
+ }
+ else
+ break;
+ }
+ else
+ break;
+ if (c_parser_next_token_is (parser, CPP_COMMA))
+ {
+ c_parser_consume_token (parser);
+ continue;
+ }
+ break;
+ }
+ if (!step)
+ step = integer_one_node;
+ }
+ else
{
- error_at (clause_loc, "%<linear%> clause step expression must "
- "be integral");
- step = integer_one_node;
+ c_expr expr = c_parser_expr_no_commas (parser, NULL);
+ expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
+ step = c_fully_fold (expr.value, false, NULL);
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
+ {
+ error_at (clause_loc, "%<linear%> clause step expression must "
+ "be integral");
+ step = integer_one_node;
+ }
}
}
@@ -15725,6 +15817,7 @@ c_parser_omp_clause_linear (c_parser *parser, tree list)
{
OMP_CLAUSE_LINEAR_STEP (c) = step;
OMP_CLAUSE_LINEAR_KIND (c) = kind;
+ OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c) = old_linear_modifier;
}
parens.skip_until_found_close (parser);
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 21a93c3..fd0a7f8 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -14478,11 +14478,13 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
need_implicitly_determined = true;
t = OMP_CLAUSE_DECL (c);
if (ort != C_ORT_OMP_DECLARE_SIMD
- && OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_DEFAULT)
+ && OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_DEFAULT
+ && OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c))
{
error_at (OMP_CLAUSE_LOCATION (c),
"modifier should not be specified in %<linear%> "
- "clause on %<simd%> or %<for%> constructs");
+ "clause on %<simd%> or %<for%> constructs when not "
+ "using OpenMP 5.2 modifiers");
OMP_CLAUSE_LINEAR_KIND (c) = OMP_CLAUSE_LINEAR_DEFAULT;
}
if (!INTEGRAL_TYPE_P (TREE_TYPE (t))