* [gomp5] Parse task modifier of reduction clauses
@ 2018-08-01 14:20 Jakub Jelinek
0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2018-08-01 14:20 UTC (permalink / raw)
To: gcc-patches
Hi!
This patch adds just the parsing and diagnostics of task reduction modifier.
Such reductions behave then differently, like task_reduction clause on
taskgroup construct when used on parallel or for/sections.
Tested on x86_64-linux, committed to gomp-5_0-branch.
2018-08-01 Jakub Jelinek <jakub@redhat.com>
* tree.h (OMP_CLAUSE_REDUCTION_TASK, OMP_CLAUSE_REDUCTION_INSCAN):
Define.
* tree-pretty-print.c (dump_omp_clause): Print reduction modifiers.
* gimplify.c (gimplify_scan_omp_clauses): Handle
OMP_CLAUSE_REDUCTION_TASK diagnostics.
gcc/c-family/
* c-omp.c (c_omp_split_clauses): Handle OMP_CLAUSE_REDUCTION_TASK.
gcc/c/
* c-parser.c (c_parser_omp_clause_reduction): Add IS_OMP argument,
parse reduction modifiers.
(c_parser_oacc_all_clauses, c_parser_omp_all_clauses): Adjust
c_parser_omp_clause_reduction callers.
gcc/cp/
* parser.c (cp_parser_omp_clause_reduction): Add IS_OMP argument,
parse reduction modifiers.
(cp_parser_oacc_all_clauses, cp_parser_omp_all_clauses): Adjust
cp_parser_omp_clause_reduction callers.
gcc/testsuite/
* c-c++-common/gomp/reduction-task-1.c: New test.
* c-c++-common/gomp/reduction-task-2.c: New test.
--- gcc/tree.h.jj 2018-07-17 17:24:39.972318592 +0200
+++ gcc/tree.h 2018-07-30 16:18:35.928699592 +0200
@@ -1614,6 +1614,14 @@ extern tree maybe_wrap_with_location (tr
(OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_REDUCTION, \
OMP_CLAUSE_IN_REDUCTION)->base.public_flag)
+/* True if a REDUCTION clause has task reduction-modifier. */
+#define OMP_CLAUSE_REDUCTION_TASK(NODE) \
+ TREE_PROTECTED (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION))
+
+/* True if a REDUCTION clause has inscan reduction-modifier. */
+#define OMP_CLAUSE_REDUCTION_INSCAN(NODE) \
+ TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION))
+
/* True if a LINEAR clause doesn't need copy in. True for iterator vars which
are always initialized inside of the loop construct, false otherwise. */
#define OMP_CLAUSE_LINEAR_NO_COPYIN(NODE) \
--- gcc/tree-pretty-print.c.jj 2018-07-10 11:32:22.271156564 +0200
+++ gcc/tree-pretty-print.c 2018-07-30 18:22:56.159264665 +0200
@@ -477,6 +477,13 @@ dump_omp_clause (pretty_printer *pp, tre
/* FALLTHRU */
case OMP_CLAUSE_REDUCTION:
pp_string (pp, "reduction(");
+ if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_REDUCTION)
+ {
+ if (OMP_CLAUSE_REDUCTION_TASK (clause))
+ pp_string (pp, "task,");
+ else if (OMP_CLAUSE_REDUCTION_INSCAN (clause))
+ pp_string (pp, "inscan,");
+ }
if (OMP_CLAUSE_REDUCTION_CODE (clause) != ERROR_MARK)
{
pp_string (pp,
--- gcc/gimplify.c.jj 2018-07-25 17:40:05.967970906 +0200
+++ gcc/gimplify.c 2018-08-01 14:34:53.945975952 +0200
@@ -7960,6 +7960,7 @@ gimplify_scan_omp_clauses (tree *list_p,
hash_map<tree, tree> *struct_map_to_clause = NULL;
tree *prev_list_p = NULL;
int handled_depend_iterators = -1;
+ int nowait = -1;
ctx = new_omp_context (region_type);
outer_ctx = ctx->outer_context;
@@ -8113,6 +8114,32 @@ gimplify_scan_omp_clauses (tree *list_p,
}
goto do_add;
case OMP_CLAUSE_REDUCTION:
+ if (OMP_CLAUSE_REDUCTION_TASK (c))
+ {
+ if (region_type == ORT_WORKSHARE)
+ {
+ if (nowait == -1)
+ nowait = omp_find_clause (*list_p,
+ OMP_CLAUSE_NOWAIT) != NULL_TREE;
+ if (nowait
+ && (outer_ctx == NULL
+ || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%<task%> reduction modifier on a construct "
+ "with a %<nowait%> clause");
+ OMP_CLAUSE_REDUCTION_TASK (c) = 0;
+ }
+ }
+ else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "invalid %<task%> reduction modifier on construct "
+ "other than %<parallel%>, %<for%> or %<sections%>");
+ OMP_CLAUSE_REDUCTION_TASK (c) = 0;
+ }
+ }
+ /* FALLTHRU */
case OMP_CLAUSE_IN_REDUCTION:
case OMP_CLAUSE_TASK_REDUCTION:
flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
@@ -9016,6 +9043,9 @@ gimplify_scan_omp_clauses (tree *list_p,
break;
case OMP_CLAUSE_NOWAIT:
+ nowait = 1;
+ break;
+
case OMP_CLAUSE_ORDERED:
case OMP_CLAUSE_UNTIED:
case OMP_CLAUSE_COLLAPSE:
--- gcc/c-family/c-omp.c.jj 2018-07-17 17:24:39.973318593 +0200
+++ gcc/c-family/c-omp.c 2018-08-01 14:04:30.178369000 +0200
@@ -1590,6 +1590,28 @@ c_omp_split_clauses (location_t loc, enu
Duplicate it on all of them, but omit on for or sections if
parallel is present. */
case OMP_CLAUSE_REDUCTION:
+ if (OMP_CLAUSE_REDUCTION_TASK (clauses))
+ {
+ if (code == OMP_SIMD /* || code == OMP_LOOP */)
+ {
+ error_at (OMP_CLAUSE_LOCATION (clauses),
+ "invalid %<task%> reduction modifier on construct "
+ "combined with %<simd%>" /* or %<loop%> */);
+ OMP_CLAUSE_REDUCTION_TASK (clauses) = 0;
+ }
+ else if (code != OMP_SECTIONS
+ && (mask & (OMP_CLAUSE_MASK_1
+ << PRAGMA_OMP_CLAUSE_SCHEDULE)) == 0
+ && (mask & (OMP_CLAUSE_MASK_1
+ << PRAGMA_OMP_CLAUSE_SCHEDULE)) == 0)
+ {
+ error_at (OMP_CLAUSE_LOCATION (clauses),
+ "invalid %<task%> reduction modifier on construct "
+ "not combined with %<parallel%>, %<for%> or "
+ "%<sections%>");
+ OMP_CLAUSE_REDUCTION_TASK (clauses) = 0;
+ }
+ }
if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
{
if (code == OMP_SIMD)
@@ -1618,9 +1640,9 @@ c_omp_split_clauses (location_t loc, enu
= OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
= OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clauses);
- OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
- cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] = c;
- s = C_OMP_CLAUSE_SPLIT_TEAMS;
+ OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
+ cclauses[C_OMP_CLAUSE_SPLIT_TEAMS] = c;
+ s = C_OMP_CLAUSE_SPLIT_PARALLEL;
}
else if ((mask & (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
--- gcc/c/c-parser.c.jj 2018-07-24 18:19:26.526677938 +0200
+++ gcc/c/c-parser.c 2018-07-31 13:53:31.320112896 +0200
@@ -13076,20 +13076,48 @@ c_parser_omp_clause_private (c_parser *p
identifier
OpenMP 5.0:
+ reduction ( reduction-modifier, reduction-operator : variable-list )
in_reduction ( reduction-operator : variable-list )
task_reduction ( reduction-operator : variable-list ) */
static tree
c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
- tree list)
+ bool is_omp, tree list)
{
location_t clause_loc = c_parser_peek_token (parser)->location;
matching_parens parens;
if (parens.require_open (parser))
{
+ bool task = false;
+ bool inscan = false;
enum tree_code code = ERROR_MARK;
tree reduc_id = NULL_TREE;
+ if (kind == OMP_CLAUSE_REDUCTION && is_omp)
+ {
+ if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
+ && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
+ {
+ c_parser_consume_token (parser);
+ c_parser_consume_token (parser);
+ }
+ else if (c_parser_next_token_is (parser, CPP_NAME)
+ && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
+ {
+ const char *p
+ = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+ if (strcmp (p, "task") == 0)
+ task = true;
+ else if (strcmp (p, "inscan") == 0)
+ inscan = true;
+ if (task || inscan)
+ {
+ c_parser_consume_token (parser);
+ c_parser_consume_token (parser);
+ }
+ }
+ }
+
switch (c_parser_peek_token (parser)->type)
{
case CPP_PLUS:
@@ -13171,6 +13199,10 @@ c_parser_omp_clause_reduction (c_parser
while (TREE_CODE (type) == ARRAY_TYPE)
type = TREE_TYPE (type);
OMP_CLAUSE_REDUCTION_CODE (c) = code;
+ if (task)
+ OMP_CLAUSE_REDUCTION_TASK (c) = 1;
+ else if (inscan)
+ OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
if (code == ERROR_MARK
|| !(INTEGRAL_TYPE_P (type)
|| TREE_CODE (type) == REAL_TYPE
@@ -14452,12 +14484,12 @@ c_parser_oacc_all_clauses (c_parser *par
case PRAGMA_OACC_CLAUSE_REDUCTION:
clauses
= c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
- clauses);
+ false, clauses);
c_name = "reduction";
break;
case PRAGMA_OACC_CLAUSE_SEQ:
clauses = c_parser_oacc_simple_clause (parser, OMP_CLAUSE_SEQ,
- clauses);
+ clauses);
c_name = "seq";
break;
case PRAGMA_OACC_CLAUSE_TILE:
@@ -14581,7 +14613,7 @@ c_parser_omp_all_clauses (c_parser *pars
case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
clauses
= c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
- clauses);
+ true, clauses);
c_name = "in_reduction";
break;
case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
@@ -14619,7 +14651,7 @@ c_parser_omp_all_clauses (c_parser *pars
case PRAGMA_OMP_CLAUSE_REDUCTION:
clauses
= c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
- clauses);
+ true, clauses);
c_name = "reduction";
break;
case PRAGMA_OMP_CLAUSE_SCHEDULE:
@@ -14633,7 +14665,7 @@ c_parser_omp_all_clauses (c_parser *pars
case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
clauses
= c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
- clauses);
+ true, clauses);
c_name = "task_reduction";
break;
case PRAGMA_OMP_CLAUSE_UNTIED:
--- gcc/cp/parser.c.jj 2018-07-25 11:42:54.123510698 +0200
+++ gcc/cp/parser.c 2018-07-31 13:56:33.842637416 +0200
@@ -32931,19 +32931,47 @@ cp_parser_omp_clause_ordered (cp_parser
id-expression
OpenMP 5.0:
+ reduction ( reduction-modifier, reduction-operator : variable-list )
in_reduction ( reduction-operator : variable-list )
task_reduction ( reduction-operator : variable-list ) */
static tree
cp_parser_omp_clause_reduction (cp_parser *parser, enum omp_clause_code kind,
- tree list)
+ bool is_omp, tree list)
{
enum tree_code code = ERROR_MARK;
tree nlist, c, id = NULL_TREE;
+ bool task = false;
+ bool inscan = false;
if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
return list;
+ if (kind == OMP_CLAUSE_REDUCTION && is_omp)
+ {
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DEFAULT)
+ && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COMMA))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ cp_lexer_consume_token (parser->lexer);
+ }
+ else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
+ && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COMMA))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+ if (strcmp (p, "task") == 0)
+ task = true;
+ else if (strcmp (p, "inscan") == 0)
+ inscan = true;
+ if (task || inscan)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ cp_lexer_consume_token (parser->lexer);
+ }
+ }
+ }
+
switch (cp_lexer_peek_token (parser->lexer)->type)
{
case CPP_PLUS: code = PLUS_EXPR; break;
@@ -33021,6 +33049,10 @@ cp_parser_omp_clause_reduction (cp_parse
for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
{
OMP_CLAUSE_REDUCTION_CODE (c) = code;
+ if (task)
+ OMP_CLAUSE_REDUCTION_TASK (c) = 1;
+ else if (inscan)
+ OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = id;
}
@@ -34272,7 +34304,7 @@ cp_parser_oacc_all_clauses (cp_parser *p
case PRAGMA_OACC_CLAUSE_REDUCTION:
clauses
= cp_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
- clauses);
+ false, clauses);
c_name = "reduction";
break;
case PRAGMA_OACC_CLAUSE_SEQ:
@@ -34422,7 +34454,7 @@ cp_parser_omp_all_clauses (cp_parser *pa
case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
clauses
= cp_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
- clauses);
+ true, clauses);
c_name = "in_reduction";
break;
case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
@@ -34466,7 +34498,7 @@ cp_parser_omp_all_clauses (cp_parser *pa
case PRAGMA_OMP_CLAUSE_REDUCTION:
clauses
= cp_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
- clauses);
+ true, clauses);
c_name = "reduction";
break;
case PRAGMA_OMP_CLAUSE_SCHEDULE:
@@ -34483,7 +34515,7 @@ cp_parser_omp_all_clauses (cp_parser *pa
clauses
= cp_parser_omp_clause_reduction (parser,
OMP_CLAUSE_TASK_REDUCTION,
- clauses);
+ true, clauses);
c_name = "task_reduction";
break;
case PRAGMA_OMP_CLAUSE_UNTIED:
--- gcc/testsuite/c-c++-common/gomp/reduction-task-1.c.jj 2018-08-01 15:14:14.318166966 +0200
+++ gcc/testsuite/c-c++-common/gomp/reduction-task-1.c 2018-07-31 16:06:16.951634432 +0200
@@ -0,0 +1,86 @@
+int v;
+extern void foo (int);
+
+void
+bar (void)
+{
+ int i;
+ #pragma omp for reduction (task, +: v)
+ for (i = 0; i < 64; i++)
+ foo (i);
+ #pragma omp sections reduction (task, +: v)
+ {
+ foo (-2);
+ #pragma omp section
+ foo (-3);
+ }
+ #pragma omp parallel reduction (task, +: v)
+ foo (-1);
+ #pragma omp parallel for reduction (task, +: v)
+ for (i = 0; i < 64; i++)
+ foo (i);
+ #pragma omp parallel sections reduction (task, +: v)
+ {
+ foo (-2);
+ #pragma omp section
+ foo (-3);
+ }
+ #pragma omp teams distribute parallel for reduction (task, +: v)
+ for (i = 0; i < 64; i++)
+ foo (i);
+ #pragma omp for reduction (default, +: v)
+ for (i = 0; i < 64; i++)
+ foo (i);
+ #pragma omp sections reduction (default, +: v)
+ {
+ foo (-2);
+ #pragma omp section
+ foo (-3);
+ }
+ #pragma omp parallel reduction (default, +: v)
+ foo (-1);
+ #pragma omp parallel for reduction (default, +: v)
+ for (i = 0; i < 64; i++)
+ foo (i);
+ #pragma omp parallel sections reduction (default, +: v)
+ {
+ foo (-2);
+ #pragma omp section
+ foo (-3);
+ }
+ #pragma omp teams distribute parallel for reduction (default, +: v)
+ for (i = 0; i < 64; i++)
+ foo (i);
+ #pragma omp for reduction (default, +: v) nowait
+ for (i = 0; i < 64; i++)
+ foo (i);
+ #pragma omp sections nowait reduction (default, +: v)
+ {
+ foo (-2);
+ #pragma omp section
+ foo (-3);
+ }
+ #pragma omp simd reduction (default, +: v)
+ for (i = 0; i < 64; i++)
+ v++;
+ #pragma omp for simd reduction (default, +: v)
+ for (i = 0; i < 64; i++)
+ v++;
+ #pragma omp parallel for simd reduction (default, +: v)
+ for (i = 0; i < 64; i++)
+ v++;
+ #pragma omp teams distribute parallel for simd reduction (default, +: v)
+ for (i = 0; i < 64; i++)
+ v++;
+ #pragma omp taskloop reduction (default, +: v)
+ for (i = 0; i < 64; i++)
+ foo (i);
+ #pragma omp taskloop simd reduction (default, +: v)
+ for (i = 0; i < 64; i++)
+ v++;
+ #pragma omp teams reduction (default, +: v)
+ foo (i);
+ #pragma omp teams distribute reduction (default, +: v)
+ for (i = 0; i < 64; i++)
+ foo (i);
+}
--- gcc/testsuite/c-c++-common/gomp/reduction-task-2.c.jj 2018-08-01 15:14:18.040177038 +0200
+++ gcc/testsuite/c-c++-common/gomp/reduction-task-2.c 2018-08-01 14:27:51.320913239 +0200
@@ -0,0 +1,40 @@
+int v;
+extern void foo (int);
+
+void
+bar (void)
+{
+ int i;
+ #pragma omp for reduction (task, +: v) nowait /* { dg-error "'task' reduction modifier on a construct with a 'nowait' clause" } */
+ for (i = 0; i < 64; i++)
+ foo (i);
+ #pragma omp sections nowait reduction (task, +: v) /* { dg-error "'task' reduction modifier on a construct with a 'nowait' clause" } */
+ {
+ foo (-2);
+ #pragma omp section
+ foo (-3);
+ }
+ #pragma omp simd reduction (task, +: v) /* { dg-error "invalid 'task' reduction modifier on construct other than 'parallel', 'for' or 'sections'" } */
+ for (i = 0; i < 64; i++)
+ v++;
+ #pragma omp for simd reduction (task, +: v) /* { dg-error "invalid 'task' reduction modifier on construct combined with 'simd'" } */
+ for (i = 0; i < 64; i++)
+ v++;
+ #pragma omp parallel for simd reduction (task, +: v) /* { dg-error "invalid 'task' reduction modifier on construct combined with 'simd'" } */
+ for (i = 0; i < 64; i++)
+ v++;
+ #pragma omp teams distribute parallel for simd reduction (task, +: v) /* { dg-error "invalid 'task' reduction modifier on construct combined with 'simd'" } */
+ for (i = 0; i < 64; i++)
+ v++;
+ #pragma omp taskloop reduction (task, +: v) /* { dg-error "invalid 'task' reduction modifier on construct other than 'parallel', 'for' or 'sections'" } */
+ for (i = 0; i < 64; i++)
+ foo (i);
+ #pragma omp taskloop simd reduction (task, +: v) /* { dg-error "invalid 'task' reduction modifier on construct combined with 'simd'" } */
+ for (i = 0; i < 64; i++)
+ v++;
+ #pragma omp teams reduction (task, +: v) /* { dg-error "invalid 'task' reduction modifier on construct other than 'parallel', 'for' or 'sections'" } */
+ foo (i);
+ #pragma omp teams distribute reduction (task, +: v) /* { dg-error "invalid 'task' reduction modifier on construct not combined with 'parallel', 'for' or 'sections'" } */
+ for (i = 0; i < 64; i++)
+ foo (i);
+}
Jakub
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2018-08-01 14:20 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-01 14:20 [gomp5] Parse task modifier of reduction clauses Jakub Jelinek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).