From 1f6b65192b3461a08b6cd7d4531735528cd313e1 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 18 Oct 2018 18:11:12 +0200 Subject: [PATCH] gimplify.c (enum omp_region_type): Add ORT_TASKLOOP and ORT_UNTIED_TASKLOOP. * gimplify.c (enum omp_region_type): Add ORT_TASKLOOP and ORT_UNTIED_TASKLOOP. (omp_default_clause): Print "taskloop" rather than "task" if ORT_*TASKLOOP. (gimplify_scan_omp_clauses): Add shared clause on parallel for combined parallel master taskloop{, simd} if taskloop has firstprivate, lastprivate or reduction clause. (gimplify_omp_for): Likewise. Use ORT_TASKLOOP or ORT_UNTIED_TASKLOOP instead of ORT_TASK or ORT_UNTIED_TASK. gcc/c-family/ * c-omp.c (c_omp_split_clauses): Add support for combined #pragma omp parallel master and #pragma omp {,parallel }master taskloop{, simd} constructs. gcc/c/ * c-parser.c (c_parser_omp_taskloop): Add forward declaration. Disallow in_reduction clause when combined with parallel master. (c_parser_omp_master): Add p_name, mask and cclauses arguments. Allow to be called while parsing combined parallel master. Parse combined master taskloop{, simd}. (c_parser_omp_parallel): Parse combined parallel master{, taskloop{, simd}} constructs. (c_parser_omp_construct) : Adjust c_parser_omp_master caller. gcc/cp/ * parser.c (cp_parser_omp_taskloop): Add forward declaration. Disallow in_reduction clause when combined with parallel master. (cp_parser_omp_master): Add p_name, mask and cclauses arguments. Allow to be called while parsing combined parallel master. Parse combined master taskloop{, simd}. (cp_parser_omp_parallel): Parse combined parallel master{, taskloop{, simd}} constructs. (cp_parser_omp_construct) : Adjust c_parser_omp_master caller. gcc/testsuite/ * c-c++-common/gomp/clauses-1.c (foo): Add ntm argument and test if and nontemporal clauses on constructs with simd. (bar): Add ntm and i3 arguments. Test if and nontemporal clauses on constructs with simd. Change if clauses on some constructs from specific to the particular constituents to one without a modifier. Add new tests for combined host teams and for new parallel master and {,parallel }master taskloop{, simd} combined constructs. (baz): New function with host teams tests. * c-c++-common/gomp/default-1.c: New test. * c-c++-common/gomp/master-combined-1.c: New test. * c-c++-common/gomp/master-combined-2.c: New test. libgomp/ * testsuite/libgomp.c-c++-common/master-combined-1.c: New test. * testsuite/libgomp.c-c++-common/taskloop-reduction-3.c: New test. * testsuite/libgomp.c-c++-common/taskloop-reduction-4.c: New test. From-SVN: r265273 --- gcc/ChangeLog.gomp | 12 ++ gcc/c-family/ChangeLog.gomp | 6 + gcc/c-family/c-omp.c | 100 ++++++++++--- gcc/c/ChangeLog.gomp | 12 ++ gcc/c/c-parser.c | 97 +++++++++++-- gcc/cp/ChangeLog.gomp | 12 ++ gcc/cp/parser.c | 100 +++++++++++-- gcc/gimplify.c | 55 +++++-- gcc/testsuite/ChangeLog.gomp | 14 ++ gcc/testsuite/c-c++-common/gomp/clauses-1.c | 135 +++++++++++++++--- gcc/testsuite/c-c++-common/gomp/default-1.c | 22 +++ .../c-c++-common/gomp/master-combined-1.c | 32 +++++ .../c-c++-common/gomp/master-combined-2.c | 13 ++ libgomp/ChangeLog.gomp | 6 + .../libgomp.c-c++-common/master-combined-1.c | 66 +++++++++ .../taskloop-reduction-3.c | 46 ++++++ .../taskloop-reduction-4.c | 65 +++++++++ 17 files changed, 725 insertions(+), 68 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/gomp/default-1.c create mode 100644 gcc/testsuite/c-c++-common/gomp/master-combined-1.c create mode 100644 gcc/testsuite/c-c++-common/gomp/master-combined-2.c create mode 100644 libgomp/testsuite/libgomp.c-c++-common/master-combined-1.c create mode 100644 libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-3.c create mode 100644 libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-4.c diff --git a/gcc/ChangeLog.gomp b/gcc/ChangeLog.gomp index 9177582ce290..3743c42cac96 100644 --- a/gcc/ChangeLog.gomp +++ b/gcc/ChangeLog.gomp @@ -1,3 +1,15 @@ +2018-10-18 Jakub Jelinek + + * gimplify.c (enum omp_region_type): Add ORT_TASKLOOP and + ORT_UNTIED_TASKLOOP. + (omp_default_clause): Print "taskloop" rather than "task" if + ORT_*TASKLOOP. + (gimplify_scan_omp_clauses): Add shared clause on parallel for + combined parallel master taskloop{, simd} if taskloop has + firstprivate, lastprivate or reduction clause. + (gimplify_omp_for): Likewise. Use ORT_TASKLOOP or + ORT_UNTIED_TASKLOOP instead of ORT_TASK or ORT_UNTIED_TASK. + 2018-10-16 Jakub Jelinek * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE__REDUCTEMP_. diff --git a/gcc/c-family/ChangeLog.gomp b/gcc/c-family/ChangeLog.gomp index a4b9be14c103..9d763eefdc6b 100644 --- a/gcc/c-family/ChangeLog.gomp +++ b/gcc/c-family/ChangeLog.gomp @@ -1,3 +1,9 @@ +2018-10-18 Jakub Jelinek + + * c-omp.c (c_omp_split_clauses): Add support for combined + #pragma omp parallel master and + #pragma omp {,parallel }master taskloop{, simd} constructs. + 2018-10-16 Jakub Jelinek * c-omp.c (c_omp_split_clauses) : For diff --git a/gcc/c-family/c-omp.c b/gcc/c-family/c-omp.c index 630d41b73156..c7d44560da50 100644 --- a/gcc/c-family/c-omp.c +++ b/gcc/c-family/c-omp.c @@ -1260,18 +1260,24 @@ c_oacc_split_loop_clauses (tree clauses, tree *not_loop_clauses, } /* This function attempts to split or duplicate clauses for OpenMP - combined/composite constructs. Right now there are 21 different + combined/composite constructs. Right now there are 26 different constructs. CODE is the innermost construct in the combined construct, and MASK allows to determine which constructs are combined together, as every construct has at least one clause that no other construct - has (except for OMP_SECTIONS, but that can be only combined with parallel). + has (except for OMP_SECTIONS, but that can be only combined with parallel, + and OMP_MASTER, which doesn't have any clauses at all). OpenMP combined/composite constructs are: #pragma omp distribute parallel for #pragma omp distribute parallel for simd #pragma omp distribute simd #pragma omp for simd + #pragma omp master taskloop + #pragma omp master taskloop simd #pragma omp parallel for #pragma omp parallel for simd + #pragma omp parallel master + #pragma omp parallel master taskloop + #pragma omp parallel master taskloop simd #pragma omp parallel sections #pragma omp target parallel #pragma omp target parallel for @@ -1305,8 +1311,9 @@ c_omp_split_clauses (location_t loc, enum tree_code code, { case OMP_FOR: case OMP_SIMD: - cclauses[C_OMP_CLAUSE_SPLIT_FOR] - = build_omp_clause (loc, OMP_CLAUSE_NOWAIT); + if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0) + cclauses[C_OMP_CLAUSE_SPLIT_FOR] + = build_omp_clause (loc, OMP_CLAUSE_NOWAIT); break; case OMP_SECTIONS: cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS] @@ -1411,8 +1418,8 @@ c_omp_split_clauses (location_t loc, enum tree_code code, else s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE; break; - /* Private clause is supported on all constructs, - it is enough to put it on the innermost one. For + /* Private clause is supported on all constructs but master, + it is enough to put it on the innermost one other than master. For #pragma omp {for,sections} put it on parallel though, as that's what we did for OpenMP 3.1. */ case OMP_CLAUSE_PRIVATE: @@ -1423,12 +1430,14 @@ c_omp_split_clauses (location_t loc, enum tree_code code, case OMP_PARALLEL: s = C_OMP_CLAUSE_SPLIT_PARALLEL; break; case OMP_DISTRIBUTE: s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE; break; case OMP_TEAMS: s = C_OMP_CLAUSE_SPLIT_TEAMS; break; + case OMP_MASTER: s = C_OMP_CLAUSE_SPLIT_PARALLEL; break; + case OMP_TASKLOOP: s = C_OMP_CLAUSE_SPLIT_TASKLOOP; break; default: gcc_unreachable (); } break; /* Firstprivate clause is supported on all constructs but - simd. Put it on the outermost of those and duplicate on teams - and parallel. */ + simd and master. Put it on the outermost of those and duplicate on + teams and parallel. */ case OMP_CLAUSE_FIRSTPRIVATE: if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0) @@ -1467,6 +1476,11 @@ c_omp_split_clauses (location_t loc, enum tree_code code, else s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE; } + else if ((mask & (OMP_CLAUSE_MASK_1 + << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0) + /* This must be + #pragma omp parallel master taskloop{, simd}. */ + s = C_OMP_CLAUSE_SPLIT_TASKLOOP; else /* This must be #pragma omp parallel{, for{, simd}, sections} @@ -1496,8 +1510,10 @@ c_omp_split_clauses (location_t loc, enum tree_code code, else if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0) { - /* This must be #pragma omp taskloop simd. */ - gcc_assert (code == OMP_SIMD); + /* This must be #pragma omp {,{,parallel }master }taskloop simd + or + #pragma omp {,parallel }master taskloop. */ + gcc_assert (code == OMP_SIMD || code == OMP_TASKLOOP); s = C_OMP_CLAUSE_SPLIT_TASKLOOP; } else @@ -1507,9 +1523,9 @@ c_omp_split_clauses (location_t loc, enum tree_code code, s = C_OMP_CLAUSE_SPLIT_FOR; } break; - /* Lastprivate is allowed on distribute, for, sections and simd. In - parallel {for{, simd},sections} we actually want to put it on - parallel rather than for or sections. */ + /* Lastprivate is allowed on distribute, for, sections, taskloop and + simd. In parallel {for{, simd},sections} we actually want to put + it on parallel rather than for or sections. */ case OMP_CLAUSE_LASTPRIVATE: if (code == OMP_DISTRIBUTE) { @@ -1536,6 +1552,11 @@ c_omp_split_clauses (location_t loc, enum tree_code code, s = C_OMP_CLAUSE_SPLIT_FOR; break; } + if (code == OMP_TASKLOOP) + { + s = C_OMP_CLAUSE_SPLIT_TASKLOOP; + break; + } gcc_assert (code == OMP_SIMD); if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0) { @@ -1552,6 +1573,16 @@ c_omp_split_clauses (location_t loc, enum tree_code code, OMP_CLAUSE_CHAIN (c) = cclauses[s]; cclauses[s] = c; } + if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0) + { + c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses), + OMP_CLAUSE_LASTPRIVATE); + OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses); + OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) + = OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (clauses); + OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP]; + cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP] = c; + } s = C_OMP_CLAUSE_SPLIT_SIMD; break; /* Shared and default clauses are allowed on parallel, teams and @@ -1561,6 +1592,19 @@ c_omp_split_clauses (location_t loc, enum tree_code code, if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0) { + if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) + != 0) + { + c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses), + OMP_CLAUSE_CODE (clauses)); + if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_SHARED) + OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses); + else + OMP_CLAUSE_DEFAULT_KIND (c) + = OMP_CLAUSE_DEFAULT_KIND (clauses); + OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; + cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] = c; + } s = C_OMP_CLAUSE_SPLIT_TASKLOOP; break; } @@ -1585,9 +1629,10 @@ c_omp_split_clauses (location_t loc, enum tree_code code, } s = C_OMP_CLAUSE_SPLIT_PARALLEL; break; - /* Reduction is allowed on simd, for, parallel, sections and teams. - Duplicate it on all of them, but omit on for or sections if - parallel is present. */ + /* Reduction is allowed on simd, for, parallel, sections, taskloop + and teams. Duplicate it on all of them, but omit on for or + sections if parallel is present. If taskloop is combined with + parallel, omit it on parallel. */ case OMP_CLAUSE_REDUCTION: if (OMP_CLAUSE_REDUCTION_TASK (clauses)) { @@ -1649,8 +1694,12 @@ c_omp_split_clauses (location_t loc, enum tree_code code, else s = C_OMP_CLAUSE_SPLIT_FOR; } - else if (code == OMP_SECTIONS || code == OMP_PARALLEL) + else if (code == OMP_SECTIONS + || code == OMP_PARALLEL + || code == OMP_MASTER) s = C_OMP_CLAUSE_SPLIT_PARALLEL; + else if (code == OMP_TASKLOOP) + s = C_OMP_CLAUSE_SPLIT_TASKLOOP; else if (code == OMP_SIMD) { if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP)) @@ -1763,7 +1812,22 @@ c_omp_split_clauses (location_t loc, enum tree_code code, } if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0) - s = C_OMP_CLAUSE_SPLIT_TASKLOOP; + { + if ((mask & (OMP_CLAUSE_MASK_1 + << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0) + { + c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses), + OMP_CLAUSE_IF); + OMP_CLAUSE_IF_MODIFIER (c) + = OMP_CLAUSE_IF_MODIFIER (clauses); + OMP_CLAUSE_IF_EXPR (c) = OMP_CLAUSE_IF_EXPR (clauses); + OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP]; + cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP] = c; + s = C_OMP_CLAUSE_SPLIT_PARALLEL; + } + else + s = C_OMP_CLAUSE_SPLIT_TASKLOOP; + } else if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0) { diff --git a/gcc/c/ChangeLog.gomp b/gcc/c/ChangeLog.gomp index e4fcbc43c571..838ee68df6b3 100644 --- a/gcc/c/ChangeLog.gomp +++ b/gcc/c/ChangeLog.gomp @@ -1,3 +1,15 @@ +2018-10-18 Jakub Jelinek + + * c-parser.c (c_parser_omp_taskloop): Add forward declaration. + Disallow in_reduction clause when combined with parallel master. + (c_parser_omp_master): Add p_name, mask and cclauses arguments. + Allow to be called while parsing combined parallel master. + Parse combined master taskloop{, simd}. + (c_parser_omp_parallel): Parse combined + parallel master{, taskloop{, simd}} constructs. + (c_parser_omp_construct) : Adjust + c_parser_omp_master caller. + 2018-10-17 Jakub Jelinek * c-parser.c (c_finish_taskloop_clauses): New function. diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 84036a9c049e..c9f9acf50135 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -16804,6 +16804,9 @@ c_parser_omp_for (location_t loc, c_parser *parser, return ret; } +static tree c_parser_omp_taskloop (location_t, c_parser *, char *, + omp_clause_mask, tree *, bool *); + /* OpenMP 2.5: # pragma omp master new-line structured-block @@ -16812,9 +16815,52 @@ c_parser_omp_for (location_t loc, c_parser *parser, */ static tree -c_parser_omp_master (location_t loc, c_parser *parser, bool *if_p) +c_parser_omp_master (location_t loc, c_parser *parser, + char *p_name, omp_clause_mask mask, tree *cclauses, + bool *if_p) { - c_parser_skip_to_pragma_eol (parser); + tree block, clauses, ret; + + strcat (p_name, " master"); + + if (c_parser_next_token_is (parser, CPP_NAME)) + { + const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); + + if (strcmp (p, "taskloop") == 0) + { + tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; + if (cclauses == NULL) + cclauses = cclauses_buf; + + c_parser_consume_token (parser); + if (!flag_openmp) /* flag_openmp_simd */ + return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses, + if_p); + block = c_begin_compound_stmt (true); + ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses, + if_p); + block = c_end_compound_stmt (loc, block, true); + if (ret == NULL_TREE) + return ret; + ret = c_finish_omp_master (loc, block); + return ret; + } + } + if (!flag_openmp) /* flag_openmp_simd */ + { + c_parser_skip_to_pragma_eol (parser, false); + return NULL_TREE; + } + + if (cclauses) + { + clauses = c_parser_omp_all_clauses (parser, mask, p_name, false); + omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses); + } + else + c_parser_skip_to_pragma_eol (parser); + return c_finish_omp_master (loc, c_parser_omp_structured_block (parser, if_p)); } @@ -17076,19 +17122,38 @@ c_parser_omp_parallel (location_t loc, c_parser *parser, c_parser_skip_to_pragma_eol (parser); return NULL_TREE; } - else if (!flag_openmp) /* flag_openmp_simd */ - { - c_parser_skip_to_pragma_eol (parser, false); - return NULL_TREE; - } else if (cclauses == NULL && c_parser_next_token_is (parser, CPP_NAME)) { const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); - if (strcmp (p, "sections") == 0) + if (strcmp (p, "master") == 0) { tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; - if (cclauses == NULL) - cclauses = cclauses_buf; + cclauses = cclauses_buf; + + c_parser_consume_token (parser); + if (!flag_openmp) /* flag_openmp_simd */ + return c_parser_omp_master (loc, parser, p_name, mask, cclauses, + if_p); + block = c_begin_omp_parallel (); + tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses, + if_p); + stmt = c_finish_omp_parallel (loc, + cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL], + block); + OMP_PARALLEL_COMBINED (stmt) = 1; + if (ret == NULL) + return ret; + return stmt; + } + else if (!flag_openmp) /* flag_openmp_simd */ + { + c_parser_skip_to_pragma_eol (parser, false); + return NULL_TREE; + } + else if (strcmp (p, "sections") == 0) + { + tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; + cclauses = cclauses_buf; c_parser_consume_token (parser); block = c_begin_omp_parallel (); @@ -17100,6 +17165,11 @@ c_parser_omp_parallel (location_t loc, c_parser *parser, return stmt; } } + else if (!flag_openmp) /* flag_openmp_simd */ + { + c_parser_skip_to_pragma_eol (parser, false); + return NULL_TREE; + } clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); if (cclauses) @@ -18892,6 +18962,10 @@ c_parser_omp_taskloop (location_t loc, c_parser *parser, strcat (p_name, " taskloop"); mask |= OMP_TASKLOOP_CLAUSE_MASK; + /* #pragma omp parallel master taskloop{, simd} disallow in_reduction + clause. */ + if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0) + mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION); if (c_parser_next_token_is (parser, CPP_NAME)) { @@ -19003,7 +19077,8 @@ c_parser_omp_construct (c_parser *parser, bool *if_p) stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p); break; case PRAGMA_OMP_MASTER: - stmt = c_parser_omp_master (loc, parser, if_p); + strcpy (p_name, "#pragma omp"); + stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p); break; case PRAGMA_OMP_PARALLEL: strcpy (p_name, "#pragma omp"); diff --git a/gcc/cp/ChangeLog.gomp b/gcc/cp/ChangeLog.gomp index 7d853b9f9d2a..63e41c8f7175 100644 --- a/gcc/cp/ChangeLog.gomp +++ b/gcc/cp/ChangeLog.gomp @@ -1,3 +1,15 @@ +2018-10-18 Jakub Jelinek + + * parser.c (cp_parser_omp_taskloop): Add forward declaration. + Disallow in_reduction clause when combined with parallel master. + (cp_parser_omp_master): Add p_name, mask and cclauses arguments. + Allow to be called while parsing combined parallel master. + Parse combined master taskloop{, simd}. + (cp_parser_omp_parallel): Parse combined + parallel master{, taskloop{, simd}} constructs. + (cp_parser_omp_construct) : Adjust + c_parser_omp_master caller. + 2018-10-17 Jakub Jelinek * semantics.c (finish_omp_reduction_clause): Call save_expr for diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index f841bc6eeb57..ae92961634b2 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -36569,15 +36569,66 @@ cp_parser_omp_for (cp_parser *parser, cp_token *pragma_tok, return ret; } +static tree cp_parser_omp_taskloop (cp_parser *, cp_token *, char *, + omp_clause_mask, tree *, bool *); + /* OpenMP 2.5: # pragma omp master new-line structured-block */ static tree -cp_parser_omp_master (cp_parser *parser, cp_token *pragma_tok, bool *if_p) +cp_parser_omp_master (cp_parser *parser, cp_token *pragma_tok, + char *p_name, omp_clause_mask mask, tree *cclauses, + bool *if_p) { - cp_parser_require_pragma_eol (parser, pragma_tok); - return c_finish_omp_master (input_location, + tree clauses, sb, ret; + unsigned int save; + location_t loc = cp_lexer_peek_token (parser->lexer)->location; + + strcat (p_name, " master"); + + if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) + { + tree id = cp_lexer_peek_token (parser->lexer)->u.value; + const char *p = IDENTIFIER_POINTER (id); + + if (strcmp (p, "taskloop") == 0) + { + tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; + if (cclauses == NULL) + cclauses = cclauses_buf; + + cp_lexer_consume_token (parser->lexer); + if (!flag_openmp) /* flag_openmp_simd */ + return cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask, + cclauses, if_p); + sb = begin_omp_structured_block (); + save = cp_parser_begin_omp_structured_block (parser); + ret = cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask, + cclauses, if_p); + cp_parser_end_omp_structured_block (parser, save); + tree body = finish_omp_structured_block (sb); + if (ret == NULL) + return ret; + return c_finish_omp_master (loc, body); + } + } + if (!flag_openmp) /* flag_openmp_simd */ + { + cp_parser_skip_to_pragma_eol (parser, pragma_tok); + return NULL_TREE; + } + + if (cclauses) + { + clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok, + false); + cp_omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses); + } + else + cp_parser_require_pragma_eol (parser, pragma_tok); + + return c_finish_omp_master (loc, cp_parser_omp_structured_block (parser, if_p)); } @@ -36819,16 +36870,34 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok, cp_parser_skip_to_pragma_eol (parser, pragma_tok); return NULL_TREE; } - else if (!flag_openmp) /* flag_openmp_simd */ - { - cp_parser_skip_to_pragma_eol (parser, pragma_tok); - return NULL_TREE; - } else if (cclauses == NULL && cp_lexer_next_token_is (parser->lexer, CPP_NAME)) { tree id = cp_lexer_peek_token (parser->lexer)->u.value; const char *p = IDENTIFIER_POINTER (id); - if (strcmp (p, "sections") == 0) + if (strcmp (p, "master") == 0) + { + tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; + cclauses = cclauses_buf; + + cp_lexer_consume_token (parser->lexer); + block = begin_omp_parallel (); + save = cp_parser_begin_omp_structured_block (parser); + tree ret = cp_parser_omp_master (parser, pragma_tok, p_name, mask, + cclauses, if_p); + cp_parser_end_omp_structured_block (parser, save); + stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL], + block); + OMP_PARALLEL_COMBINED (stmt) = 1; + if (ret == NULL_TREE) + return ret; + return stmt; + } + else if (!flag_openmp) /* flag_openmp_simd */ + { + cp_parser_skip_to_pragma_eol (parser, pragma_tok); + return NULL_TREE; + } + else if (strcmp (p, "sections") == 0) { tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; cclauses = cclauses_buf; @@ -36844,6 +36913,11 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok, return stmt; } } + else if (!flag_openmp) /* flag_openmp_simd */ + { + cp_parser_skip_to_pragma_eol (parser, pragma_tok); + return NULL_TREE; + } clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok, cclauses == NULL); @@ -39089,6 +39163,10 @@ cp_parser_omp_taskloop (cp_parser *parser, cp_token *pragma_tok, strcat (p_name, " taskloop"); mask |= OMP_TASKLOOP_CLAUSE_MASK; + /* #pragma omp parallel master taskloop{, simd} disallow in_reduction + clause. */ + if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0) + mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION); if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) { @@ -39451,7 +39529,9 @@ cp_parser_omp_construct (cp_parser *parser, cp_token *pragma_tok, bool *if_p) if_p); break; case PRAGMA_OMP_MASTER: - stmt = cp_parser_omp_master (parser, pragma_tok, if_p); + strcpy (p_name, "#pragma omp"); + stmt = cp_parser_omp_master (parser, pragma_tok, p_name, mask, NULL, + if_p); break; case PRAGMA_OMP_PARALLEL: strcpy (p_name, "#pragma omp"); diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 3f355855bde6..0bb0435d720b 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -130,6 +130,8 @@ enum omp_region_type ORT_TASK = 0x10, ORT_UNTIED_TASK = ORT_TASK | 1, + ORT_TASKLOOP = ORT_TASK | 2, + ORT_UNTIED_TASKLOOP = ORT_UNTIED_TASK | 2, ORT_TEAMS = 0x20, ORT_COMBINED_TEAMS = ORT_TEAMS | 1, @@ -6992,6 +6994,8 @@ omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl, if (ctx->region_type & ORT_PARALLEL) rtype = "parallel"; + else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP) + rtype = "taskloop"; else if (ctx->region_type & ORT_TASK) rtype = "task"; else if (ctx->region_type & ORT_TEAMS) @@ -8976,6 +8980,31 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, " or private in outer context", DECL_NAME (decl)); } do_notice: + if ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP + && outer_ctx + && outer_ctx->region_type == ORT_COMBINED_PARALLEL + && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)) + { + splay_tree_node on + = splay_tree_lookup (outer_ctx->variables, + (splay_tree_key)decl); + if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0) + { + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION + && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF + && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE + || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE + && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) + == POINTER_TYPE)))) + omp_firstprivatize_variable (outer_ctx, decl); + else + omp_add_variable (outer_ctx, decl, + GOVD_SEEN | GOVD_SHARED); + omp_notice_variable (outer_ctx, decl, true); + } + } if (outer_ctx) omp_notice_variable (outer_ctx, decl, true); if (check_non_private @@ -10421,9 +10450,9 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) break; case OMP_TASKLOOP: if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED)) - ort = ORT_UNTIED_TASK; + ort = ORT_UNTIED_TASKLOOP; else - ort = ORT_TASK; + ort = ORT_TASKLOOP; break; case OMP_SIMD: ort = ORT_SIMD; @@ -10731,7 +10760,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) else if (omp_check_private (outer, decl, false)) outer = NULL; } - else if (((outer->region_type & ORT_TASK) != 0) + else if (((outer->region_type & ORT_TASKLOOP) + == ORT_TASKLOOP) && outer->combined_loop && !omp_check_private (gimplify_omp_ctxp, decl, false)) @@ -10770,8 +10800,12 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) outer = NULL; } if (outer && outer->outer_context - && (outer->outer_context->region_type - & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS) + && ((outer->outer_context->region_type + & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS + || (((outer->region_type & ORT_TASKLOOP) + == ORT_TASKLOOP) + && (outer->outer_context->region_type + == ORT_COMBINED_PARALLEL)))) { outer = outer->outer_context; n = splay_tree_lookup (outer->variables, @@ -10818,7 +10852,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) else if (omp_check_private (outer, decl, false)) outer = NULL; } - else if (((outer->region_type & ORT_TASK) != 0) + else if (((outer->region_type & ORT_TASKLOOP) + == ORT_TASKLOOP) && outer->combined_loop && !omp_check_private (gimplify_omp_ctxp, decl, false)) @@ -10857,8 +10892,12 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p) outer = NULL; } if (outer && outer->outer_context - && (outer->outer_context->region_type - & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS) + && ((outer->outer_context->region_type + & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS + || (((outer->region_type & ORT_TASKLOOP) + == ORT_TASKLOOP) + && (outer->outer_context->region_type + == ORT_COMBINED_PARALLEL)))) { outer = outer->outer_context; n = splay_tree_lookup (outer->variables, diff --git a/gcc/testsuite/ChangeLog.gomp b/gcc/testsuite/ChangeLog.gomp index d134e31b3d2a..5a471f84ec6d 100644 --- a/gcc/testsuite/ChangeLog.gomp +++ b/gcc/testsuite/ChangeLog.gomp @@ -1,3 +1,17 @@ +2018-10-18 Jakub Jelinek + + * c-c++-common/gomp/clauses-1.c (foo): Add ntm argument and + test if and nontemporal clauses on constructs with simd. + (bar): Add ntm and i3 arguments. Test if and nontemporal clauses + on constructs with simd. Change if clauses on some constructs from + specific to the particular constituents to one without a modifier. + Add new tests for combined host teams and for new parallel master + and {,parallel }master taskloop{, simd} combined constructs. + (baz): New function with host teams tests. + * c-c++-common/gomp/default-1.c: New test. + * c-c++-common/gomp/master-combined-1.c: New test. + * c-c++-common/gomp/master-combined-2.c: New test. + 2018-10-17 Jakub Jelinek * gcc.dg/gomp/reduction-2.c: New test. diff --git a/gcc/testsuite/c-c++-common/gomp/clauses-1.c b/gcc/testsuite/c-c++-common/gomp/clauses-1.c index 1bbc1464216c..652270cc0bdd 100644 --- a/gcc/testsuite/c-c++-common/gomp/clauses-1.c +++ b/gcc/testsuite/c-c++-common/gomp/clauses-1.c @@ -9,7 +9,7 @@ int f, l, ll, r, r2; void foo (int d, int m, int i1, int i2, int p, int *idp, int s, - int nte, int tl, int nth, int g, int nta, int fi, int pp, int *q) + int nte, int tl, int nth, int g, int nta, int fi, int pp, int *q, int ntm) { #pragma omp distribute parallel for \ private (p) firstprivate (f) collapse(1) dist_schedule(static, 16) \ @@ -19,26 +19,50 @@ foo (int d, int m, int i1, int i2, int p, int *idp, int s, ll++; #pragma omp distribute parallel for simd \ private (p) firstprivate (f) collapse(1) dist_schedule(static, 16) \ - if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) \ - lastprivate (l) schedule(static, 4) \ + if (parallel: i2) if(simd: i1) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) \ + lastprivate (l) schedule(static, 4) nontemporal(ntm) \ safelen(8) simdlen(4) aligned(q: 32) for (int i = 0; i < 64; i++) ll++; #pragma omp distribute simd \ private (p) firstprivate (f) collapse(1) dist_schedule(static, 16) \ - safelen(8) simdlen(4) aligned(q: 32) reduction(+:r) + safelen(8) simdlen(4) aligned(q: 32) reduction(+:r) if(i1) nontemporal(ntm) for (int i = 0; i < 64; i++) ll++; } #pragma omp end declare target void -bar (int d, int m, int i1, int i2, int p, int *idp, int s, - int nte, int tl, int nth, int g, int nta, int fi, int pp, int *q, int *dd) +baz (int d, int m, int i1, int i2, int p, int *idp, int s, + int nte, int tl, int nth, int g, int nta, int fi, int pp, int *q, int ntm) +{ + #pragma omp distribute parallel for \ + private (p) firstprivate (f) collapse(1) dist_schedule(static, 16) \ + if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) \ + lastprivate (l) schedule(static, 4) copyin(t) + for (int i = 0; i < 64; i++) + ll++; + #pragma omp distribute parallel for simd \ + private (p) firstprivate (f) collapse(1) dist_schedule(static, 16) \ + if (parallel: i2) if(simd: i1) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) \ + lastprivate (l) schedule(static, 4) nontemporal(ntm) \ + safelen(8) simdlen(4) aligned(q: 32) copyin(t) + for (int i = 0; i < 64; i++) + ll++; + #pragma omp distribute simd \ + private (p) firstprivate (f) collapse(1) dist_schedule(static, 16) \ + safelen(8) simdlen(4) aligned(q: 32) reduction(+:r) if(i1) nontemporal(ntm) + for (int i = 0; i < 64; i++) + ll++; +} + +void +bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s, + int nte, int tl, int nth, int g, int nta, int fi, int pp, int *q, int *dd, int ntm) { #pragma omp for simd \ private (p) firstprivate (f) lastprivate (l) linear (ll:1) reduction(+:r) schedule(static, 4) collapse(1) nowait \ - safelen(8) simdlen(4) aligned(q: 32) + safelen(8) simdlen(4) aligned(q: 32) nontemporal(ntm) if(i1) for (int i = 0; i < 64; i++) ll++; #pragma omp parallel for \ @@ -47,9 +71,9 @@ bar (int d, int m, int i1, int i2, int p, int *idp, int s, for (int i = 0; i < 64; i++) ll++; #pragma omp parallel for simd \ - private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) copyin(t) reduction(+:r) num_threads (nth) proc_bind(spread) \ + private (p) firstprivate (f) if (i2) default(shared) shared(s) copyin(t) reduction(+:r) num_threads (nth) proc_bind(spread) \ lastprivate (l) linear (ll:1) schedule(static, 4) collapse(1) \ - safelen(8) simdlen(4) aligned(q: 32) + safelen(8) simdlen(4) aligned(q: 32) nontemporal(ntm) for (int i = 0; i < 64; i++) ll++; #pragma omp parallel sections \ @@ -76,7 +100,7 @@ bar (int d, int m, int i1, int i2, int p, int *idp, int s, device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \ if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) \ lastprivate (l) linear (ll:1) schedule(static, 4) collapse(1) \ - safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0]) + safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0]) nontemporal(ntm) if (simd: i3) for (int i = 0; i < 64; i++) ll++; #pragma omp target teams \ @@ -103,38 +127,38 @@ bar (int d, int m, int i1, int i2, int p, int *idp, int s, collapse(1) dist_schedule(static, 16) \ if (parallel: i2) num_threads (nth) proc_bind(spread) \ lastprivate (l) schedule(static, 4) \ - safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0]) + safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0]) nontemporal(ntm) if (simd: i3) for (int i = 0; i < 64; i++) ll++; #pragma omp target teams distribute simd \ - device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \ + device(d) map (tofrom: m) if (i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \ shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \ collapse(1) dist_schedule(static, 16) \ - safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0]) + safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0]) nontemporal(ntm) for (int i = 0; i < 64; i++) ll++; #pragma omp target simd \ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \ safelen(8) simdlen(4) lastprivate (l) linear(ll: 1) aligned(q: 32) reduction(+:r) \ - nowait depend(inout: dd[0]) + nowait depend(inout: dd[0]) nontemporal(ntm) if(simd:i3) for (int i = 0; i < 64; i++) ll++; #pragma omp taskgroup task_reduction(+:r2) #pragma omp taskloop simd \ - private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) final(fi) mergeable priority (pp) \ - safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) + private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) if(simd: i2) final(fi) mergeable priority (pp) \ + safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm) for (int i = 0; i < 64; i++) ll++; #pragma omp taskgroup task_reduction(+:r) #pragma omp taskloop simd \ - private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) final(fi) mergeable nogroup priority (pp) \ - safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) in_reduction(+:r) + private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(i1) final(fi) mergeable nogroup priority (pp) \ + safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) in_reduction(+:r) nontemporal(ntm) for (int i = 0; i < 64; i++) ll++; #pragma omp taskwait #pragma omp taskloop simd \ private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) if(taskloop: i1) final(fi) priority (pp) \ - safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(+:r) + safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(+:r) if (simd: i3) nontemporal(ntm) for (int i = 0; i < 64; i++) ll++; #pragma omp target nowait depend(inout: dd[0]) @@ -157,14 +181,83 @@ bar (int d, int m, int i1, int i2, int p, int *idp, int s, collapse(1) dist_schedule(static, 16) \ if (parallel: i2) num_threads (nth) proc_bind(spread) \ lastprivate (l) schedule(static, 4) \ - safelen(8) simdlen(4) aligned(q: 32) + safelen(8) simdlen(4) aligned(q: 32) if (simd: i3) nontemporal(ntm) for (int i = 0; i < 64; i++) ll++; #pragma omp target #pragma omp teams distribute simd \ private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \ collapse(1) dist_schedule(static, 16) \ - safelen(8) simdlen(4) aligned(q: 32) + safelen(8) simdlen(4) aligned(q: 32) if(i3) nontemporal(ntm) + for (int i = 0; i < 64; i++) + ll++; + #pragma omp teams distribute parallel for \ + private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \ + collapse(1) dist_schedule(static, 16) \ + if (parallel: i2) num_threads (nth) proc_bind(spread) \ + lastprivate (l) schedule(static, 4) copyin(t) + for (int i = 0; i < 64; i++) + ll++; + #pragma omp teams distribute parallel for simd \ + private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \ + collapse(1) dist_schedule(static, 16) \ + if (parallel: i2) num_threads (nth) proc_bind(spread) \ + lastprivate (l) schedule(static, 4) \ + safelen(8) simdlen(4) aligned(q: 32) if (simd: i3) nontemporal(ntm) copyin(t) + for (int i = 0; i < 64; i++) + ll++; + #pragma omp teams distribute simd \ + private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \ + collapse(1) dist_schedule(static, 16) \ + safelen(8) simdlen(4) aligned(q: 32) if(i3) nontemporal(ntm) + for (int i = 0; i < 64; i++) + ll++; + #pragma omp parallel master \ + private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) reduction(+:r) \ + num_threads (nth) proc_bind(spread) copyin(t) + ; + #pragma omp taskgroup task_reduction (+:r2) + #pragma omp master taskloop \ + private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) final(fi) mergeable priority (pp) \ + reduction(default, +:r) in_reduction(+:r2) + for (int i = 0; i < 64; i++) + ll++; + #pragma omp taskgroup task_reduction (+:r2) + #pragma omp master taskloop simd \ + private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) if(simd: i2) final(fi) mergeable priority (pp) \ + safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm) + for (int i = 0; i < 64; i++) + ll++; + #pragma omp parallel master taskloop \ + private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) final(fi) mergeable priority (pp) \ + reduction(default, +:r) if (parallel: i2) num_threads (nth) proc_bind(spread) copyin(t) + for (int i = 0; i < 64; i++) + ll++; + #pragma omp parallel master taskloop simd \ + private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) if(simd: i2) final(fi) mergeable priority (pp) \ + safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) nontemporal(ntm) if (parallel: i2) num_threads (nth) proc_bind(spread) copyin(t) + for (int i = 0; i < 64; i++) + ll++; + #pragma omp taskgroup task_reduction (+:r2) + #pragma omp master taskloop \ + private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp) \ + reduction(default, +:r) in_reduction(+:r2) + for (int i = 0; i < 64; i++) + ll++; + #pragma omp taskgroup task_reduction (+:r2) + #pragma omp master taskloop simd \ + private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp) \ + safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm) + for (int i = 0; i < 64; i++) + ll++; + #pragma omp parallel master taskloop \ + private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp) \ + reduction(default, +:r) num_threads (nth) proc_bind(spread) copyin(t) + for (int i = 0; i < 64; i++) + ll++; + #pragma omp parallel master taskloop simd \ + private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp) \ + safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) nontemporal(ntm) num_threads (nth) proc_bind(spread) copyin(t) for (int i = 0; i < 64; i++) ll++; } diff --git a/gcc/testsuite/c-c++-common/gomp/default-1.c b/gcc/testsuite/c-c++-common/gomp/default-1.c new file mode 100644 index 000000000000..6525483c44e7 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/default-1.c @@ -0,0 +1,22 @@ +void +foo (void) +{ + int x = 0, i; + #pragma omp task default(none) /* { dg-error "enclosing 'task'" } */ + { + x++; /* { dg-error "'x' not specified in enclosing 'task'" } */ + } + #pragma omp taskloop default(none) /* { dg-error "enclosing 'taskloop'" } */ + for (i = 0; i < 64; i++) + { + x++; /* { dg-error "'x' not specified in enclosing 'taskloop'" } */ + } + #pragma omp teams default(none) /* { dg-error "enclosing 'teams'" } */ + { + x++; /* { dg-error "'x' not specified in enclosing 'teams'" } */ + } + #pragma omp parallel default(none) /* { dg-error "enclosing 'parallel'" } */ + { + x++; /* { dg-error "'x' not specified in enclosing 'parallel'" } */ + } +} diff --git a/gcc/testsuite/c-c++-common/gomp/master-combined-1.c b/gcc/testsuite/c-c++-common/gomp/master-combined-1.c new file mode 100644 index 000000000000..b11f5db10de2 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/master-combined-1.c @@ -0,0 +1,32 @@ +void bar (int *); + +void +foo (int *a) +{ + int i, j, k, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0; + #pragma omp parallel master default(none) private (k) + bar (&k); + #pragma omp parallel default(none) firstprivate(a) shared(x, y, z) + { + #pragma omp master taskloop reduction (+:x) default(none) firstprivate(a) + for (i = 0; i < 64; i++) + x += a[i]; + #pragma omp master taskloop simd reduction (+:y) default(none) firstprivate(a) private (i) + for (i = 0; i < 64; i++) + y += a[i]; + #pragma omp master taskloop simd collapse(2) reduction (+:z) default(none) firstprivate(a) private (i, j) + for (j = 0; j < 1; j++) + for (i = 0; i < 64; ++i) + z += a[i]; + } + #pragma omp parallel master taskloop reduction (+:u) default(none) firstprivate(a) + for (i = 0; i < 64; i++) + u += a[i]; + #pragma omp parallel master taskloop simd reduction (+:v) default(none) firstprivate(a) + for (i = 0; i < 64; i++) + v += a[i]; + #pragma omp parallel master taskloop simd collapse(2) reduction (+:w) default(none) firstprivate(a) + for (j = 0; j < 1; j++) + for (i = 0; i < 64; ++i) + w += a[i]; +} diff --git a/gcc/testsuite/c-c++-common/gomp/master-combined-2.c b/gcc/testsuite/c-c++-common/gomp/master-combined-2.c new file mode 100644 index 000000000000..4f7b57409aaf --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/master-combined-2.c @@ -0,0 +1,13 @@ +void +foo (int *a) +{ + int i, r = 0, s = 0; + #pragma omp taskgroup task_reduction(+:r) + #pragma omp parallel master taskloop in_reduction(+:r) /* { dg-error "'in_reduction' is not valid for '#pragma omp parallel master taskloop'" } */ + for (i = 0; i < 64; i++) + r += a[i]; + #pragma omp taskgroup task_reduction(+:s) + #pragma omp parallel master taskloop simd in_reduction(+:s) /* { dg-error "'in_reduction' is not valid for '#pragma omp parallel master taskloop simd'" } */ + for (i = 0; i < 64; i++) + s += a[i]; +} diff --git a/libgomp/ChangeLog.gomp b/libgomp/ChangeLog.gomp index cbab22f43442..a58fc2cbf987 100644 --- a/libgomp/ChangeLog.gomp +++ b/libgomp/ChangeLog.gomp @@ -1,3 +1,9 @@ +2018-10-18 Jakub Jelinek + + * testsuite/libgomp.c-c++-common/master-combined-1.c: New test. + * testsuite/libgomp.c-c++-common/taskloop-reduction-3.c: New test. + * testsuite/libgomp.c-c++-common/taskloop-reduction-4.c: New test. + 2018-10-16 Jakub Jelinek * task.c (GOMP_taskgroup_reduction_register): Add ialias. diff --git a/libgomp/testsuite/libgomp.c-c++-common/master-combined-1.c b/libgomp/testsuite/libgomp.c-c++-common/master-combined-1.c new file mode 100644 index 000000000000..3e6da095122e --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/master-combined-1.c @@ -0,0 +1,66 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ +/* { dg-additional-options "-std=c99" { target c } } */ +/* { dg-additional-options "-msse2" { target sse2_runtime } } */ +/* { dg-additional-options "-mavx" { target avx_runtime } } */ + +#include +#include + +#define N 64 + +int +main () +{ + int p, *q, i, l; + int a[N]; + q = a; + #pragma omp parallel master num_threads(4) private (p) shared(a) + { + int i; + p = omp_get_thread_num (); + if (p != 0) + abort (); + #pragma omp taskloop nogroup + for (i = 0; i < N; ++i) + { + if (omp_get_thread_num () >= 4) + abort (); + a[i] = i; + } + } + #pragma omp parallel num_threads(4) + { + #pragma omp master taskloop lastprivate (i, l) firstprivate (q) + for (i = 0; i != N; i = i + 1) + l = q[i]; + } + if (i != N || l != N - 1) + abort (); + #pragma omp parallel master taskloop num_threads(4) \ + lastprivate (i, l) firstprivate (q) + for (i = 0; i < N - 5; i += 2) + if (q[i] != i) + abort (); + else + l = q[i]; + if (i != N - 4 || l != N - 6) + abort (); + #pragma omp parallel master taskloop simd num_threads(4) + for (i = 0; i < N; i++) + a[i] = 2 * a[i]; + if (i != N) + abort (); + #pragma omp parallel num_threads(4) + { + int j; + #pragma omp master taskloop simd collapse(2) + for (i = 0; i < 2; i += 2) + for (j = 0; j < N; j++) + a[j] = a[j] + 1; + } + for (i = 0; i < N; i++) + if (a[i] != 2 * i + 1) + abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-3.c b/libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-3.c new file mode 100644 index 000000000000..5a1c154ddd63 --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-3.c @@ -0,0 +1,46 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ +/* { dg-additional-options "-std=c99" { target c } } */ +/* { dg-additional-options "-msse2" { target sse2_runtime } } */ +/* { dg-additional-options "-mavx" { target avx_runtime } } */ + +#define N 1024 +long int u[N], m, n; + +__attribute__((noipa)) void +foo (void) +{ + int i; + #pragma omp taskloop simd reduction (+:m) grainsize (64) + for (i = 0; i < N; ++i) + m += u[i]; +} + +__attribute__((noipa)) void +bar (int x) +{ + int i; + #pragma omp taskloop simd in_reduction (+:n) grainsize (64) nogroup + for (i = (x & 1) * (N / 2); i < (x & 1) * (N / 2) + (N / 2); i++) + n += 2 * u[i]; +} + +int +main () +{ + int i; + for (i = 0; i < N; ++i) + u[i] = i; + #pragma omp parallel master + { + foo (); + #pragma omp taskgroup task_reduction (+:n) + { + bar (0); + bar (1); + } + } + if (m != (long)(N - 1) * (N / 2) || n != (long)(N - 1) * N) + __builtin_abort (); + return 0; +} diff --git a/libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-4.c b/libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-4.c new file mode 100644 index 000000000000..c1c29b37414f --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-4.c @@ -0,0 +1,65 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ +/* { dg-additional-options "-std=c99" { target c } } */ +/* { dg-additional-options "-msse2" { target sse2_runtime } } */ +/* { dg-additional-options "-mavx" { target avx_runtime } } */ + +#include +#include + +#define N 1024 +long int u[N], m, n, o; + +__attribute__((noipa)) void +foo (void) +{ + int i = -1; + #pragma omp master taskloop simd reduction (+:m) grainsize (64) + for (i = 0; i < N; ++i) + m += u[i]; + if (i != (omp_get_thread_num () ? -1 : N)) + abort (); +} + +__attribute__((noipa)) void +bar (int x) +{ + int i = -1; + #pragma omp master taskloop simd in_reduction (+:n) grainsize (64) + for (i = (x & 1) * (N / 2); i < (x & 1) * (N / 2) + (N / 2); i++) + n += 2 * u[i]; + if (i != (omp_get_thread_num () ? -1 : (x & 1) * (N / 2) + (N / 2))) + abort (); +} + +__attribute__((noipa)) void +baz (void) +{ + int i; + #pragma omp parallel master taskloop simd reduction (+:o) grainsize (64) + for (i = 0; i < N; ++i) + o += u[i]; + if (i != N) + abort (); +} + +int +main () +{ + int i; + for (i = 0; i < N; ++i) + u[i] = i; + #pragma omp parallel + { + foo (); + #pragma omp taskgroup task_reduction (+:n) + { + bar (0); + bar (1); + } + } + baz (); + if (m != (long)(N - 1) * (N / 2) || n != (long)(N - 1) * N || o != m) + abort (); + return 0; +} -- 2.47.2