diff options
41 files changed, 969 insertions, 40 deletions
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 65d8c1c..025123a 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -1201,7 +1201,8 @@ enum c_omp_clause_split C_OMP_CLAUSE_SPLIT_COUNT, C_OMP_CLAUSE_SPLIT_SECTIONS = C_OMP_CLAUSE_SPLIT_FOR, C_OMP_CLAUSE_SPLIT_TASKLOOP = C_OMP_CLAUSE_SPLIT_FOR, - C_OMP_CLAUSE_SPLIT_LOOP = C_OMP_CLAUSE_SPLIT_FOR + C_OMP_CLAUSE_SPLIT_LOOP = C_OMP_CLAUSE_SPLIT_FOR, + C_OMP_CLAUSE_SPLIT_MASKED = C_OMP_CLAUSE_SPLIT_DISTRIBUTE }; enum c_omp_region_type @@ -1215,6 +1216,7 @@ enum c_omp_region_type }; extern tree c_finish_omp_master (location_t, tree); +extern tree c_finish_omp_masked (location_t, tree, tree); extern tree c_finish_omp_taskgroup (location_t, tree, tree); extern tree c_finish_omp_critical (location_t, tree, tree, tree); extern tree c_finish_omp_ordered (location_t, tree, tree); diff --git a/gcc/c-family/c-omp.c b/gcc/c-family/c-omp.c index e70974d..54eba61 100644 --- a/gcc/c-family/c-omp.c +++ b/gcc/c-family/c-omp.c @@ -86,6 +86,20 @@ c_finish_omp_master (location_t loc, tree stmt) return t; } +/* Complete a #pragma omp masked construct. BODY is the structured-block + that follows the pragma. LOC is the location of the #pragma. */ + +tree +c_finish_omp_masked (location_t loc, tree body, tree clauses) +{ + tree stmt = make_node (OMP_MASKED); + TREE_TYPE (stmt) = void_type_node; + OMP_MASKED_BODY (stmt) = body; + OMP_MASKED_CLAUSES (stmt) = clauses; + SET_EXPR_LOCATION (stmt, loc); + return add_stmt (stmt); +} + /* Complete a #pragma omp taskgroup construct. BODY is the structured-block that follows the pragma. LOC is the location of the #pragma. */ @@ -1542,11 +1556,16 @@ c_oacc_split_loop_clauses (tree clauses, tree *not_loop_clauses, #pragma omp distribute parallel for simd #pragma omp distribute simd #pragma omp for simd + #pragma omp masked taskloop + #pragma omp masked taskloop simd #pragma omp master taskloop #pragma omp master taskloop simd #pragma omp parallel for #pragma omp parallel for simd #pragma omp parallel loop + #pragma omp parallel masked + #pragma omp parallel masked taskloop + #pragma omp parallel masked taskloop simd #pragma omp parallel master #pragma omp parallel master taskloop #pragma omp parallel master taskloop simd @@ -1651,6 +1670,9 @@ c_omp_split_clauses (location_t loc, enum tree_code code, case OMP_CLAUSE_BIND: s = C_OMP_CLAUSE_SPLIT_LOOP; break; + case OMP_CLAUSE_FILTER: + s = C_OMP_CLAUSE_SPLIT_MASKED; + break; /* Duplicate this to all of taskloop, distribute, for, simd and loop. */ case OMP_CLAUSE_COLLAPSE: @@ -1700,10 +1722,10 @@ 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 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. */ + /* Private clause is supported on all constructs but master/masked, + it is enough to put it on the innermost one other than + master/masked. For #pragma omp {for,sections} put it on parallel + though, as that's what we did for OpenMP 3.1. */ case OMP_CLAUSE_PRIVATE: switch (code) { @@ -1713,14 +1735,15 @@ c_omp_split_clauses (location_t loc, enum tree_code code, 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_MASKED: s = C_OMP_CLAUSE_SPLIT_PARALLEL; break; case OMP_TASKLOOP: s = C_OMP_CLAUSE_SPLIT_TASKLOOP; break; case OMP_LOOP: s = C_OMP_CLAUSE_SPLIT_LOOP; break; default: gcc_unreachable (); } break; /* Firstprivate clause is supported on all constructs but - simd, master and loop. Put it on the outermost of those and - duplicate on teams and parallel. */ + simd, master, masked and loop. 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) @@ -1773,7 +1796,7 @@ 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 parallel master taskloop{, simd}. */ + #pragma omp parallel mas{ked,ter} taskloop{, simd}. */ s = C_OMP_CLAUSE_SPLIT_TASKLOOP; else /* This must be @@ -1805,9 +1828,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 {,{,parallel }master }taskloop simd + /* This must be + #pragma omp {,{,parallel }mas{ked,ter} }taskloop simd or - #pragma omp {,parallel }master taskloop. */ + #pragma omp {,parallel }mas{ked,ter} taskloop. */ gcc_assert (code == OMP_SIMD || code == OMP_TASKLOOP); s = C_OMP_CLAUSE_SPLIT_TASKLOOP; } @@ -2044,7 +2068,8 @@ c_omp_split_clauses (location_t loc, enum tree_code code, } else if (code == OMP_SECTIONS || code == OMP_PARALLEL - || code == OMP_MASTER) + || code == OMP_MASTER + || code == OMP_MASKED) s = C_OMP_CLAUSE_SPLIT_PARALLEL; else if (code == OMP_TASKLOOP) s = C_OMP_CLAUSE_SPLIT_TASKLOOP; @@ -2455,7 +2480,8 @@ c_omp_split_clauses (location_t loc, enum tree_code code, gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_TARGET] == NULL_TREE); if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)) == 0) gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_TEAMS] == NULL_TREE); - if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0) + if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0 + && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)) == 0) gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE] == NULL_TREE); if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) == 0) gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] == NULL_TREE); @@ -2975,8 +3001,8 @@ static const struct c_omp_directive omp_directives[] = { C_OMP_DIR_STANDALONE, false }, */ { "loop", nullptr, nullptr, PRAGMA_OMP_LOOP, C_OMP_DIR_CONSTRUCT, true }, - /* { "masked", nullptr, nullptr, PRAGMA_OMP_MASKED, - C_OMP_DIR_CONSTRUCT, true }, */ + { "masked", nullptr, nullptr, PRAGMA_OMP_MASKED, + C_OMP_DIR_CONSTRUCT, true }, { "master", nullptr, nullptr, PRAGMA_OMP_MASTER, C_OMP_DIR_CONSTRUCT, true }, /* { "metadirective", nullptr, nullptr, PRAGMA_OMP_METADIRECTIVE, diff --git a/gcc/c-family/c-pragma.c b/gcc/c-family/c-pragma.c index f46b5b9..b466a27 100644 --- a/gcc/c-family/c-pragma.c +++ b/gcc/c-family/c-pragma.c @@ -1343,6 +1343,7 @@ static const struct omp_pragma_def omp_pragmas_simd[] = { { "distribute", PRAGMA_OMP_DISTRIBUTE }, { "for", PRAGMA_OMP_FOR }, { "loop", PRAGMA_OMP_LOOP }, + { "masked", PRAGMA_OMP_MASKED }, { "master", PRAGMA_OMP_MASTER }, { "ordered", PRAGMA_OMP_ORDERED }, { "parallel", PRAGMA_OMP_PARALLEL }, diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h index abd6667..b7ec6e5 100644 --- a/gcc/c-family/c-pragma.h +++ b/gcc/c-family/c-pragma.h @@ -57,6 +57,7 @@ enum pragma_kind { PRAGMA_OMP_FLUSH, PRAGMA_OMP_FOR, PRAGMA_OMP_LOOP, + PRAGMA_OMP_MASKED, PRAGMA_OMP_MASTER, PRAGMA_OMP_ORDERED, PRAGMA_OMP_PARALLEL, @@ -104,6 +105,7 @@ enum pragma_omp_clause { PRAGMA_OMP_CLAUSE_DEVICE, PRAGMA_OMP_CLAUSE_DEVICE_TYPE, PRAGMA_OMP_CLAUSE_DIST_SCHEDULE, + PRAGMA_OMP_CLAUSE_FILTER, PRAGMA_OMP_CLAUSE_FINAL, PRAGMA_OMP_CLAUSE_FIRSTPRIVATE, PRAGMA_OMP_CLAUSE_FOR, diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 195c137..ca6e56a 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -12696,7 +12696,9 @@ c_parser_omp_clause_name (c_parser *parser) result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE; break; case 'f': - if (!strcmp ("final", p)) + if (!strcmp ("filter", p)) + result = PRAGMA_OMP_CLAUSE_FILTER; + else if (!strcmp ("final", p)) result = PRAGMA_OMP_CLAUSE_FINAL; else if (!strcmp ("finalize", p)) result = PRAGMA_OACC_CLAUSE_FINALIZE; @@ -13948,6 +13950,38 @@ c_parser_omp_clause_hint (c_parser *parser, tree list) return list; } +/* OpenMP 5.1: + filter ( integer-expression ) */ + +static tree +c_parser_omp_clause_filter (c_parser *parser, tree list) +{ + location_t hint_loc = c_parser_peek_token (parser)->location; + matching_parens parens; + if (parens.require_open (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); + tree c, t = expr.value; + t = c_fully_fold (t, false, NULL); + if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) + { + c_parser_error (parser, "expected integer expression"); + return list; + } + parens.skip_until_found_close (parser); + check_no_duplicate_clause (list, OMP_CLAUSE_FILTER, "filter"); + + c = build_omp_clause (hint_loc, OMP_CLAUSE_FILTER); + OMP_CLAUSE_FILTER_EXPR (c) = t; + OMP_CLAUSE_CHAIN (c) = list; + list = c; + } + + return list; +} + /* OpenMP 4.5: defaultmap ( tofrom : scalar ) @@ -16410,6 +16444,10 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask, clauses = c_parser_omp_clause_detach (parser, clauses); c_name = "detach"; break; + case PRAGMA_OMP_CLAUSE_FILTER: + clauses = c_parser_omp_clause_filter (parser, clauses); + c_name = "filter"; + break; case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE: clauses = c_parser_omp_clause_firstprivate (parser, clauses); c_name = "firstprivate"; @@ -18975,6 +19013,70 @@ c_parser_omp_master (location_t loc, c_parser *parser, if_p)); } +/* OpenMP 5.1: + # pragma omp masked masked-clauses new-line + structured-block + + LOC is the location of the #pragma token. +*/ + +#define OMP_MASKED_CLAUSE_MASK \ + (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER) + +static tree +c_parser_omp_masked (location_t loc, c_parser *parser, + char *p_name, omp_clause_mask mask, tree *cclauses, + bool *if_p) +{ + tree block, clauses, ret; + + strcat (p_name, " masked"); + mask |= OMP_MASKED_CLAUSE_MASK; + + 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_masked (loc, block, + cclauses[C_OMP_CLAUSE_SPLIT_MASKED]); + OMP_MASKED_COMBINED (ret) = 1; + return ret; + } + } + 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) + { + omp_split_clauses (loc, OMP_MASKED, mask, clauses, cclauses); + clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED]; + } + + return c_finish_omp_masked (loc, c_parser_omp_structured_block (parser, + if_p), + clauses); +} + /* OpenMP 2.5: # pragma omp ordered new-line structured-block @@ -19237,7 +19339,36 @@ c_parser_omp_parallel (location_t loc, c_parser *parser, else if (c_parser_next_token_is (parser, CPP_NAME)) { const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); - if (cclauses == NULL && strcmp (p, "master") == 0) + if (cclauses == NULL && strcmp (p, "masked") == 0) + { + tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; + cclauses = cclauses_buf; + + c_parser_consume_token (parser); + if (!flag_openmp) /* flag_openmp_simd */ + return c_parser_omp_masked (loc, parser, p_name, mask, cclauses, + if_p); + block = c_begin_omp_parallel (); + tree ret = c_parser_omp_masked (loc, parser, p_name, mask, cclauses, + if_p); + stmt = c_finish_omp_parallel (loc, + cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL], + block); + if (ret == NULL) + return ret; + /* masked does have just filter clause, but during gimplification + isn't represented by a gimplification omp context, so for + #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED, + so that + #pragma omp parallel masked + #pragma omp taskloop simd lastprivate (x) + isn't confused with + #pragma omp parallel masked taskloop simd lastprivate (x) */ + if (OMP_MASKED_COMBINED (ret)) + OMP_PARALLEL_COMBINED (stmt) = 1; + return stmt; + } + else if (cclauses == NULL && strcmp (p, "master") == 0) { tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; cclauses = cclauses_buf; @@ -21815,6 +21946,10 @@ c_parser_omp_construct (c_parser *parser, bool *if_p) strcpy (p_name, "#pragma omp"); stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p); break; + case PRAGMA_OMP_MASKED: + strcpy (p_name, "#pragma omp"); + stmt = c_parser_omp_masked (loc, parser, p_name, mask, NULL, if_p); + break; case PRAGMA_OMP_MASTER: strcpy (p_name, "#pragma omp"); stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p); diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index eb5c87d..0c07af61 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -15158,6 +15158,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) case OMP_CLAUSE_THREADS: case OMP_CLAUSE_SIMD: case OMP_CLAUSE_HINT: + case OMP_CLAUSE_FILTER: case OMP_CLAUSE_DEFAULTMAP: case OMP_CLAUSE_BIND: case OMP_CLAUSE_NUM_GANGS: diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index b7fe4b4..edb69ae 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -36004,7 +36004,9 @@ cp_parser_omp_clause_name (cp_parser *parser) result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE; break; case 'f': - if (!strcmp ("final", p)) + if (!strcmp ("filter", p)) + result = PRAGMA_OMP_CLAUSE_FILTER; + else if (!strcmp ("final", p)) result = PRAGMA_OMP_CLAUSE_FINAL; else if (!strcmp ("finalize", p)) result = PRAGMA_OACC_CLAUSE_FINALIZE; @@ -37340,6 +37342,34 @@ cp_parser_omp_clause_hint (cp_parser *parser, tree list, location_t location) return c; } +/* OpenMP 5.1: + filter ( integer-expression ) */ + +static tree +cp_parser_omp_clause_filter (cp_parser *parser, tree list, location_t location) +{ + tree t, c; + + matching_parens parens; + if (!parens.require_open (parser)) + return list; + + t = cp_parser_assignment_expression (parser); + + if (t == error_mark_node + || !parens.require_close (parser)) + cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true, + /*or_comma=*/false, + /*consume_paren=*/true); + check_no_duplicate_clause (list, OMP_CLAUSE_FILTER, "filter", location); + + c = build_omp_clause (location, OMP_CLAUSE_FILTER); + OMP_CLAUSE_FILTER_EXPR (c) = t; + OMP_CLAUSE_CHAIN (c) = list; + + return c; +} + /* OpenMP 4.5: defaultmap ( tofrom : scalar ) @@ -39449,6 +39479,11 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask, token->location, false); c_name = "default"; break; + case PRAGMA_OMP_CLAUSE_FILTER: + clauses = cp_parser_omp_clause_filter (parser, clauses, + token->location); + c_name = "filter"; + break; case PRAGMA_OMP_CLAUSE_FINAL: clauses = cp_parser_omp_clause_final (parser, clauses, token->location); c_name = "final"; @@ -41985,6 +42020,73 @@ cp_parser_omp_master (cp_parser *parser, cp_token *pragma_tok, cp_parser_omp_structured_block (parser, if_p)); } +/* OpenMP 5.1: + # pragma omp masked masked-clauses new-line + structured-block */ + +#define OMP_MASKED_CLAUSE_MASK \ + (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER) + +static tree +cp_parser_omp_masked (cp_parser *parser, cp_token *pragma_tok, + char *p_name, omp_clause_mask mask, tree *cclauses, + bool *if_p) +{ + tree clauses, sb, ret; + unsigned int save; + location_t loc = cp_lexer_peek_token (parser->lexer)->location; + + strcat (p_name, " masked"); + mask |= OMP_MASKED_CLAUSE_MASK; + + 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; + ret = c_finish_omp_masked (loc, body, + cclauses[C_OMP_CLAUSE_SPLIT_MASKED]); + OMP_MASKED_COMBINED (ret) = 1; + return ret; + } + } + 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); + if (cclauses) + { + cp_omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses); + clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED]; + } + + return c_finish_omp_masked (loc, + cp_parser_omp_structured_block (parser, if_p), + clauses); +} + /* OpenMP 2.5: # pragma omp ordered new-line structured-block @@ -42238,7 +42340,37 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok, { tree id = cp_lexer_peek_token (parser->lexer)->u.value; const char *p = IDENTIFIER_POINTER (id); - if (cclauses == NULL && strcmp (p, "master") == 0) + if (cclauses == NULL && strcmp (p, "masked") == 0) + { + tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; + cclauses = cclauses_buf; + + cp_lexer_consume_token (parser->lexer); + if (!flag_openmp) /* flag_openmp_simd */ + return cp_parser_omp_masked (parser, pragma_tok, p_name, mask, + cclauses, if_p); + block = begin_omp_parallel (); + save = cp_parser_begin_omp_structured_block (parser); + tree ret = cp_parser_omp_masked (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); + if (ret == NULL_TREE) + return ret; + /* masked does have just filter clause, but during gimplification + isn't represented by a gimplification omp context, so for + #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED, + so that + #pragma omp parallel masked + #pragma omp taskloop simd lastprivate (x) + isn't confused with + #pragma omp parallel masked taskloop simd lastprivate (x) */ + if (OMP_MASKED_COMBINED (ret)) + OMP_PARALLEL_COMBINED (stmt) = 1; + return stmt; + } + else if (cclauses == NULL && strcmp (p, "master") == 0) { tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; cclauses = cclauses_buf; @@ -45824,6 +45956,11 @@ cp_parser_omp_construct (cp_parser *parser, cp_token *pragma_tok, bool *if_p) stmt = cp_parser_omp_loop (parser, pragma_tok, p_name, mask, NULL, if_p); break; + case PRAGMA_OMP_MASKED: + strcpy (p_name, "#pragma omp"); + stmt = cp_parser_omp_masked (parser, pragma_tok, p_name, mask, NULL, + if_p); + break; case PRAGMA_OMP_MASTER: strcpy (p_name, "#pragma omp"); stmt = cp_parser_omp_master (parser, pragma_tok, p_name, mask, NULL, @@ -46464,6 +46601,7 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p) case PRAGMA_OMP_DISTRIBUTE: case PRAGMA_OMP_FOR: case PRAGMA_OMP_LOOP: + case PRAGMA_OMP_MASKED: case PRAGMA_OMP_MASTER: case PRAGMA_OMP_PARALLEL: case PRAGMA_OMP_SECTIONS: diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 42ea51c..0870ccd 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -17394,6 +17394,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort, case OMP_CLAUSE_PRIORITY: case OMP_CLAUSE_ORDERED: case OMP_CLAUSE_HINT: + case OMP_CLAUSE_FILTER: case OMP_CLAUSE_NUM_GANGS: case OMP_CLAUSE_NUM_WORKERS: case OMP_CLAUSE_VECTOR_LENGTH: @@ -18786,6 +18787,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, break; case OMP_SECTIONS: + case OMP_MASKED: omp_parallel_combined_clauses = NULL; /* FALLTHRU */ case OMP_SINGLE: diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 2e23818..0198d2d 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -8204,6 +8204,29 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) } break; + case OMP_CLAUSE_FILTER: + t = OMP_CLAUSE_FILTER_EXPR (c); + if (t == error_mark_node) + remove = true; + else if (!type_dependent_expression_p (t) + && !INTEGRAL_TYPE_P (TREE_TYPE (t))) + { + error_at (OMP_CLAUSE_LOCATION (c), + "%<filter%> expression must be integral"); + remove = true; + } + else + { + t = mark_rvalue_use (t); + if (!processing_template_decl) + { + t = maybe_constant_value (t); + t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); + } + OMP_CLAUSE_FILTER_EXPR (c) = t; + } + break; + case OMP_CLAUSE_IS_DEVICE_PTR: case OMP_CLAUSE_USE_DEVICE_PTR: field_ok = (ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP; diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c index fa7d4de..832d5c3 100644 --- a/gcc/gimple-low.c +++ b/gcc/gimple-low.c @@ -334,6 +334,7 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data) case GIMPLE_OMP_SECTION: case GIMPLE_OMP_SINGLE: case GIMPLE_OMP_MASTER: + case GIMPLE_OMP_MASKED: case GIMPLE_OMP_TASKGROUP: case GIMPLE_OMP_ORDERED: case GIMPLE_OMP_SCAN: diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index d6e63d6..1bccad1 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -1658,6 +1658,35 @@ dump_gimple_omp_taskgroup (pretty_printer *buffer, const gimple *gs, } } +/* Dump a GIMPLE_OMP_MASKED tuple on the pretty_printer BUFFER. */ + +static void +dump_gimple_omp_masked (pretty_printer *buffer, const gimple *gs, + int spc, dump_flags_t flags) +{ + if (flags & TDF_RAW) + { + dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs, + gimple_omp_body (gs)); + dump_omp_clauses (buffer, gimple_omp_masked_clauses (gs), spc, flags); + dump_gimple_fmt (buffer, spc, flags, " >"); + } + else + { + pp_string (buffer, "#pragma omp masked"); + dump_omp_clauses (buffer, gimple_omp_masked_clauses (gs), spc, flags); + if (!gimple_seq_empty_p (gimple_omp_body (gs))) + { + newline_and_indent (buffer, spc + 2); + pp_left_brace (buffer); + pp_newline (buffer); + dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags); + newline_and_indent (buffer, spc + 2); + pp_right_brace (buffer); + } + } +} + /* Dump a GIMPLE_OMP_TARGET tuple on the pretty_printer BUFFER. */ static void @@ -2722,6 +2751,10 @@ pp_gimple_stmt_1 (pretty_printer *buffer, const gimple *gs, int spc, dump_gimple_omp_taskgroup (buffer, gs, spc, flags); break; + case GIMPLE_OMP_MASKED: + dump_gimple_omp_masked (buffer, gs, spc, flags); + break; + case GIMPLE_OMP_MASTER: case GIMPLE_OMP_SECTION: dump_gimple_omp_block (buffer, gs, spc, flags); diff --git a/gcc/gimple-walk.c b/gcc/gimple-walk.c index 18884c4..9dd2e86 100644 --- a/gcc/gimple-walk.c +++ b/gcc/gimple-walk.c @@ -682,6 +682,7 @@ walk_gimple_stmt (gimple_stmt_iterator *gsi, walk_stmt_fn callback_stmt, /* FALL THROUGH. */ case GIMPLE_OMP_CRITICAL: case GIMPLE_OMP_MASTER: + case GIMPLE_OMP_MASKED: case GIMPLE_OMP_TASKGROUP: case GIMPLE_OMP_ORDERED: case GIMPLE_OMP_SCAN: diff --git a/gcc/gimple.c b/gcc/gimple.c index 383da98..23bfc7f 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -1038,6 +1038,21 @@ gimple_build_omp_master (gimple_seq body) return p; } +/* Build a GIMPLE_OMP_MASKED statement. + + BODY is the sequence of statements to be executed by the selected thread(s). */ + +gimple * +gimple_build_omp_masked (gimple_seq body, tree clauses) +{ + gimple *p = gimple_alloc (GIMPLE_OMP_MASKED, 0); + gimple_omp_masked_set_clauses (p, clauses); + if (body) + gimple_omp_set_body (p, body); + + return p; +} + /* Build a GIMPLE_OMP_TASKGROUP statement. BODY is the sequence of statements to be executed by the taskgroup @@ -2031,6 +2046,11 @@ gimple_copy (gimple *stmt) gimple_omp_set_body (copy, new_seq); break; + case GIMPLE_OMP_MASKED: + t = unshare_expr (gimple_omp_masked_clauses (stmt)); + gimple_omp_masked_set_clauses (copy, t); + goto copy_omp_body; + case GIMPLE_TRANSACTION: new_seq = gimple_seq_copy (gimple_transaction_body ( as_a <gtransaction *> (stmt))); diff --git a/gcc/gimple.def b/gcc/gimple.def index 0ac0cf7..e66546c 100644 --- a/gcc/gimple.def +++ b/gcc/gimple.def @@ -279,6 +279,10 @@ DEFGSCODE(GIMPLE_OMP_FOR, "gimple_omp_for", GSS_OMP_FOR) BODY is the sequence of statements to execute in the master section. */ DEFGSCODE(GIMPLE_OMP_MASTER, "gimple_omp_master", GSS_OMP) +/* GIMPLE_OMP_MASKED <BODY, CLAUSES> represents #pragma omp masked. + BODY is the sequence of statements to execute in the masked section. */ +DEFGSCODE(GIMPLE_OMP_MASKED, "gimple_omp_masked", GSS_OMP_SINGLE_LAYOUT) + /* GIMPLE_OMP_TASKGROUP <BODY, CLAUSES> represents #pragma omp taskgroup. BODY is the sequence of statements inside the taskgroup section. CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */ diff --git a/gcc/gimple.h b/gcc/gimple.h index 31d7dd0..7fd483d 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -1560,6 +1560,7 @@ gomp_task *gimple_build_omp_task (gimple_seq, tree, tree, tree, tree, tree, tree); gimple *gimple_build_omp_section (gimple_seq); gimple *gimple_build_omp_master (gimple_seq); +gimple *gimple_build_omp_masked (gimple_seq, tree); gimple *gimple_build_omp_taskgroup (gimple_seq, tree); gomp_continue *gimple_build_omp_continue (tree, tree); gomp_ordered *gimple_build_omp_ordered (gimple_seq, tree); @@ -1836,6 +1837,7 @@ gimple_has_substatements (gimple *g) case GIMPLE_TRY: case GIMPLE_OMP_FOR: case GIMPLE_OMP_MASTER: + case GIMPLE_OMP_MASKED: case GIMPLE_OMP_TASKGROUP: case GIMPLE_OMP_ORDERED: case GIMPLE_OMP_SECTION: @@ -5205,6 +5207,40 @@ gimple_omp_taskgroup_set_clauses (gimple *gs, tree clauses) } +/* Return the clauses associated with OMP_MASTER statement GS. */ + +static inline tree +gimple_omp_masked_clauses (const gimple *gs) +{ + GIMPLE_CHECK (gs, GIMPLE_OMP_MASKED); + return + static_cast <const gimple_statement_omp_single_layout *> (gs)->clauses; +} + + +/* Return a pointer to the clauses associated with OMP masked statement + GS. */ + +static inline tree * +gimple_omp_masked_clauses_ptr (gimple *gs) +{ + GIMPLE_CHECK (gs, GIMPLE_OMP_MASKED); + return &static_cast <gimple_statement_omp_single_layout *> (gs)->clauses; +} + + +/* Set CLAUSES to be the clauses associated with OMP masked statement + GS. */ + +static inline void +gimple_omp_masked_set_clauses (gimple *gs, tree clauses) +{ + GIMPLE_CHECK (gs, GIMPLE_OMP_MASKED); + static_cast <gimple_statement_omp_single_layout *> (gs)->clauses + = clauses; +} + + /* Return the kind of the OMP_FOR statemement G. */ static inline int @@ -6493,6 +6529,7 @@ gimple_return_set_retval (greturn *gs, tree retval) case GIMPLE_OMP_TEAMS: \ case GIMPLE_OMP_SECTION: \ case GIMPLE_OMP_MASTER: \ + case GIMPLE_OMP_MASKED: \ case GIMPLE_OMP_TASKGROUP: \ case GIMPLE_OMP_ORDERED: \ case GIMPLE_OMP_CRITICAL: \ diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 21ff32e..eadbf83 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -5632,6 +5632,7 @@ is_gimple_stmt (tree t) case OMP_SECTION: case OMP_SINGLE: case OMP_MASTER: + case OMP_MASKED: case OMP_TASKGROUP: case OMP_ORDERED: case OMP_CRITICAL: @@ -10102,6 +10103,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, case OMP_CLAUSE_PRIORITY: case OMP_CLAUSE_GRAINSIZE: case OMP_CLAUSE_NUM_TASKS: + case OMP_CLAUSE_FILTER: case OMP_CLAUSE_HINT: case OMP_CLAUSE_ASYNC: case OMP_CLAUSE_WAIT: @@ -10110,9 +10112,20 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, case OMP_CLAUSE_VECTOR_LENGTH: case OMP_CLAUSE_WORKER: case OMP_CLAUSE_VECTOR: - if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL, - is_gimple_val, fb_rvalue) == GS_ERROR) - remove = true; + if (OMP_CLAUSE_OPERAND (c, 0) + && !is_gimple_min_invariant (OMP_CLAUSE_OPERAND (c, 0))) + { + if (error_operand_p (OMP_CLAUSE_OPERAND (c, 0))) + { + remove = true; + break; + } + /* All these clauses care about value, not a particular decl, + so try to force it into a SSA_NAME or fresh temporary. */ + OMP_CLAUSE_OPERAND (c, 0) + = get_initialized_tmp_var (OMP_CLAUSE_OPERAND (c, 0), + pre_p, NULL, true); + } break; case OMP_CLAUSE_GANG: @@ -11222,6 +11235,7 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p, case OMP_CLAUSE_NOGROUP: case OMP_CLAUSE_THREADS: case OMP_CLAUSE_SIMD: + case OMP_CLAUSE_FILTER: case OMP_CLAUSE_HINT: case OMP_CLAUSE_DEFAULTMAP: case OMP_CLAUSE_ORDER: @@ -14766,6 +14780,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, case OMP_SECTION: case OMP_MASTER: + case OMP_MASKED: case OMP_ORDERED: case OMP_CRITICAL: case OMP_SCAN: @@ -14788,6 +14803,15 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, case OMP_ORDERED: g = gimplify_omp_ordered (*expr_p, body); break; + case OMP_MASKED: + gimplify_scan_omp_clauses (&OMP_MASKED_CLAUSES (*expr_p), + pre_p, ORT_WORKSHARE, OMP_MASKED); + gimplify_adjust_omp_clauses (pre_p, body, + &OMP_MASKED_CLAUSES (*expr_p), + OMP_MASKED); + g = gimple_build_omp_masked (body, + OMP_MASKED_CLAUSES (*expr_p)); + break; case OMP_CRITICAL: gimplify_scan_omp_clauses (&OMP_CRITICAL_CLAUSES (*expr_p), pre_p, ORT_WORKSHARE, OMP_CRITICAL); @@ -15161,6 +15185,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, && code != OMP_FOR && code != OACC_LOOP && code != OMP_MASTER + && code != OMP_MASKED && code != OMP_TASKGROUP && code != OMP_ORDERED && code != OMP_PARALLEL diff --git a/gcc/omp-expand.c b/gcc/omp-expand.c index 9fd1c65..1d4b39e 100644 --- a/gcc/omp-expand.c +++ b/gcc/omp-expand.c @@ -8460,6 +8460,7 @@ expand_omp_synch (struct omp_region *region) si = gsi_last_nondebug_bb (entry_bb); gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_MASTER + || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_MASKED || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_TASKGROUP || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ORDERED || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CRITICAL @@ -9947,6 +9948,7 @@ expand_omp (struct omp_region *region) } /* FALLTHRU */ case GIMPLE_OMP_MASTER: + case GIMPLE_OMP_MASKED: case GIMPLE_OMP_TASKGROUP: case GIMPLE_OMP_CRITICAL: case GIMPLE_OMP_TEAMS: @@ -10266,6 +10268,7 @@ omp_make_gimple_edges (basic_block bb, struct omp_region **region, case GIMPLE_OMP_SINGLE: case GIMPLE_OMP_TEAMS: case GIMPLE_OMP_MASTER: + case GIMPLE_OMP_MASKED: case GIMPLE_OMP_TASKGROUP: case GIMPLE_OMP_CRITICAL: case GIMPLE_OMP_SECTION: diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 926087d..22ba579 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -1466,6 +1466,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx) case OMP_CLAUSE_NUM_WORKERS: case OMP_CLAUSE_VECTOR_LENGTH: case OMP_CLAUSE_DETACH: + case OMP_CLAUSE_FILTER: if (ctx->outer) scan_omp_op (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer); break; @@ -1868,6 +1869,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx) case OMP_CLAUSE__SIMT_: case OMP_CLAUSE_IF_PRESENT: case OMP_CLAUSE_FINALIZE: + case OMP_CLAUSE_FILTER: case OMP_CLAUSE__CONDTEMP_: break; @@ -3426,6 +3428,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx) case GIMPLE_OMP_SINGLE: case GIMPLE_OMP_ORDERED: case GIMPLE_OMP_MASTER: + case GIMPLE_OMP_MASKED: case GIMPLE_OMP_TASK: case GIMPLE_OMP_CRITICAL: if (is_gimple_call (stmt)) @@ -3436,14 +3439,15 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx) error_at (gimple_location (stmt), "barrier region may not be closely nested inside " "of work-sharing, %<loop%>, %<critical%>, " - "%<ordered%>, %<master%>, explicit %<task%> or " - "%<taskloop%> region"); + "%<ordered%>, %<master%>, %<masked%>, explicit " + "%<task%> or %<taskloop%> region"); return false; } error_at (gimple_location (stmt), "work-sharing region may not be closely nested inside " "of work-sharing, %<loop%>, %<critical%>, %<ordered%>, " - "%<master%>, explicit %<task%> or %<taskloop%> region"); + "%<master%>, %<masked%>, explicit %<task%> or " + "%<taskloop%> region"); return false; case GIMPLE_OMP_PARALLEL: case GIMPLE_OMP_TEAMS: @@ -3458,6 +3462,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx) } break; case GIMPLE_OMP_MASTER: + case GIMPLE_OMP_MASKED: for (; ctx != NULL; ctx = ctx->outer) switch (gimple_code (ctx->stmt)) { @@ -3470,9 +3475,11 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx) case GIMPLE_OMP_SINGLE: case GIMPLE_OMP_TASK: error_at (gimple_location (stmt), - "%<master%> region may not be closely nested inside " + "%qs region may not be closely nested inside " "of work-sharing, %<loop%>, explicit %<task%> or " - "%<taskloop%> region"); + "%<taskloop%> region", + gimple_code (stmt) == GIMPLE_OMP_MASTER + ? "master" : "masked"); return false; case GIMPLE_OMP_PARALLEL: case GIMPLE_OMP_TEAMS: @@ -4079,6 +4086,12 @@ scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p, scan_omp (gimple_omp_body_ptr (stmt), ctx); break; + case GIMPLE_OMP_MASKED: + ctx = new_omp_context (stmt, ctx); + scan_sharing_clauses (gimple_omp_masked_clauses (stmt), ctx); + scan_omp (gimple_omp_body_ptr (stmt), ctx); + break; + case GIMPLE_OMP_TASKGROUP: ctx = new_omp_context (stmt, ctx); scan_sharing_clauses (gimple_omp_taskgroup_clauses (stmt), ctx); @@ -8675,7 +8688,7 @@ lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx) } -/* Expand code for an OpenMP master directive. */ +/* Expand code for an OpenMP master or masked directive. */ static void lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx) @@ -8685,9 +8698,20 @@ lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx) gbind *bind; location_t loc = gimple_location (stmt); gimple_seq tseq; + tree filter = integer_zero_node; push_gimplify_context (); + if (gimple_code (stmt) == GIMPLE_OMP_MASKED) + { + filter = omp_find_clause (gimple_omp_masked_clauses (stmt), + OMP_CLAUSE_FILTER); + if (filter) + filter = fold_convert (integer_type_node, + OMP_CLAUSE_FILTER_EXPR (filter)); + else + filter = integer_zero_node; + } block = make_node (BLOCK); bind = gimple_build_bind (NULL, NULL, block); gsi_replace (gsi_p, bind, true); @@ -8695,7 +8719,7 @@ lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx) bfn_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM); x = build_call_expr_loc (loc, bfn_decl, 0); - x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node); + x = build2 (EQ_EXPR, boolean_type_node, x, filter); x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab)); tseq = NULL; gimplify_and_add (x, &tseq); @@ -13869,6 +13893,7 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx) lower_omp_single (gsi_p, ctx); break; case GIMPLE_OMP_MASTER: + case GIMPLE_OMP_MASKED: ctx = maybe_lookup_ctx (stmt); gcc_assert (ctx); lower_omp_master (gsi_p, ctx); @@ -14246,6 +14271,7 @@ diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p, case GIMPLE_OMP_SINGLE: case GIMPLE_OMP_SECTION: case GIMPLE_OMP_MASTER: + case GIMPLE_OMP_MASKED: case GIMPLE_OMP_ORDERED: case GIMPLE_OMP_SCAN: case GIMPLE_OMP_CRITICAL: @@ -14307,6 +14333,7 @@ diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p, case GIMPLE_OMP_SINGLE: case GIMPLE_OMP_SECTION: case GIMPLE_OMP_MASTER: + case GIMPLE_OMP_MASKED: case GIMPLE_OMP_ORDERED: case GIMPLE_OMP_SCAN: case GIMPLE_OMP_CRITICAL: diff --git a/gcc/testsuite/c-c++-common/goacc/uninit-if-clause.c b/gcc/testsuite/c-c++-common/goacc/uninit-if-clause.c index 7f78d72..683ac1b 100644 --- a/gcc/testsuite/c-c++-common/goacc/uninit-if-clause.c +++ b/gcc/testsuite/c-c++-common/goacc/uninit-if-clause.c @@ -1,6 +1,5 @@ /* { dg-do compile } */ /* { dg-additional-options "-Wuninitialized" } */ -/* { dg-excess-errors "PR70392" { xfail c++ } } */ #include <stdbool.h> @@ -14,25 +13,25 @@ main (void) #pragma acc parallel if(l) /* { dg-warning "is used uninitialized" } */ ; - #pragma acc parallel if(b) /* { dg-warning "is used uninitialized" "" { xfail c++ } } */ + #pragma acc parallel if(b) /* { dg-warning "is used uninitialized" } */ ; #pragma acc kernels if(l2) /* { dg-warning "is used uninitialized" } */ ; - #pragma acc kernels if(b2) /* { dg-warning "is used uninitialized" "" { xfail c++ } } */ + #pragma acc kernels if(b2) /* { dg-warning "is used uninitialized" } */ ; #pragma acc data if(l3) /* { dg-warning "is used uninitialized" } */ ; - #pragma acc data if(b3) /* { dg-warning "is used uninitialized" "" { xfail c++ } } */ + #pragma acc data if(b3) /* { dg-warning "is used uninitialized" } */ ; #pragma acc update if(l4) self(i) /* { dg-warning "is used uninitialized" } */ ; - #pragma acc update if(b4) self(i2) /* { dg-warning "is used uninitialized" "" { xfail c++ } } */ + #pragma acc update if(b4) self(i2) /* { dg-warning "is used uninitialized" } */ ; } diff --git a/gcc/testsuite/c-c++-common/gomp/clause-dups-1.c b/gcc/testsuite/c-c++-common/gomp/clause-dups-1.c index 3dde058..7b71ad3 100644 --- a/gcc/testsuite/c-c++-common/gomp/clause-dups-1.c +++ b/gcc/testsuite/c-c++-common/gomp/clause-dups-1.c @@ -203,7 +203,8 @@ f1 (int *p) i = p[0]++; #pragma omp atomic capture hint(0) hint (0) /* { dg-error "too many 'hint' clauses" } */ i = p[0]++; - + #pragma omp masked filter (0) filter (0) /* { dg-error "too many 'filter' clauses" } */ + f0 (); } #pragma omp declare simd simdlen (4) simdlen (4) /* { dg-error "too many 'simdlen' clauses" } */ diff --git a/gcc/testsuite/c-c++-common/gomp/clauses-1.c b/gcc/testsuite/c-c++-common/gomp/clauses-1.c index 682442af..378c7bf 100644 --- a/gcc/testsuite/c-c++-common/gomp/clauses-1.c +++ b/gcc/testsuite/c-c++-common/gomp/clauses-1.c @@ -273,6 +273,10 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s, private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) reduction(+:r) \ num_threads (nth) proc_bind(spread) copyin(t) allocate (f) ; + #pragma omp parallel masked \ + private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) reduction(+:r) \ + num_threads (nth) proc_bind(spread) copyin(t) allocate (f) filter (d) + ; #pragma omp taskgroup task_reduction (+:r2) allocate (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) \ @@ -280,23 +284,47 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s, for (int i = 0; i < 64; i++) ll++; #pragma omp taskgroup task_reduction (+:r2) allocate (r2) + #pragma omp masked 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) allocate (f) filter (d) + for (int i = 0; i < 64; i++) + ll++; + #pragma omp taskgroup task_reduction (+:r2) allocate (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) \ order(concurrent) allocate (f) for (int i = 0; i < 64; i++) ll++; + #pragma omp taskgroup task_reduction (+:r2) allocate (r2) + #pragma omp masked 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) \ + order(concurrent) allocate (f) filter (d) + 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) allocate (f) for (int i = 0; i < 64; i++) ll++; + #pragma omp parallel masked 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) allocate (f) filter (d) + 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) \ order(concurrent) allocate (f) for (int i = 0; i < 64; i++) ll++; + #pragma omp parallel masked 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) \ + order(concurrent) allocate (f) filter (d) + for (int i = 0; i < 64; i++) + ll++; #pragma omp taskgroup task_reduction (+:r2) allocate (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) \ @@ -304,23 +332,47 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s, for (int i = 0; i < 64; i++) ll++; #pragma omp taskgroup task_reduction (+:r2) allocate (r2) + #pragma omp mastked 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) filter (d) + for (int i = 0; i < 64; i++) + ll++; + #pragma omp taskgroup task_reduction (+:r2) allocate (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) \ order(concurrent) allocate (f) for (int i = 0; i < 64; i++) ll++; + #pragma omp taskgroup task_reduction (+:r2) allocate (r2) + #pragma omp masked 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) \ + order(concurrent) allocate (f) filter (d) + 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) allocate (f) for (int i = 0; i < 64; i++) ll++; + #pragma omp parallel masked 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) allocate (f) filter (d) + 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) \ order(concurrent) allocate (f) for (int i = 0; i < 64; i++) ll++; + #pragma omp parallel masked 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) \ + order(concurrent) allocate (f) filter (d) + for (int i = 0; i < 64; i++) + ll++; #pragma omp loop bind(thread) order(concurrent) \ private (p) lastprivate (l) collapse(1) reduction(+:r) for (l = 0; l < 64; ++l) diff --git a/gcc/testsuite/c-c++-common/gomp/clauses-5.c b/gcc/testsuite/c-c++-common/gomp/clauses-5.c index 35e16f0..87e53a9 100644 --- a/gcc/testsuite/c-c++-common/gomp/clauses-5.c +++ b/gcc/testsuite/c-c++-common/gomp/clauses-5.c @@ -49,4 +49,6 @@ foo (int *p) ; #pragma omp critical (baz) hint (2, 3) /* { dg-error "expected" } */ ; + #pragma omp masked filter (3, 4) /* { dg-error "expected" } */ + ; } diff --git a/gcc/testsuite/c-c++-common/gomp/masked-1.c b/gcc/testsuite/c-c++-common/gomp/masked-1.c new file mode 100644 index 0000000..36c2e49 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/masked-1.c @@ -0,0 +1,23 @@ +void bar (void); + +void +foo (int x, int *a) +{ + #pragma omp masked + bar (); + #pragma omp masked filter (0) + bar (); + #pragma omp masked filter (7) + bar (); + #pragma omp masked filter (x) + bar (); + #pragma omp masked taskloop simd filter (x) grainsize (12) simdlen (4) + for (int i = 0; i < 128; i++) + a[i] = i; + #pragma omp parallel masked filter (x) firstprivate (x) + bar (); + #pragma omp masked + #pragma omp masked filter (0) + #pragma omp masked filter (x) + ; +} diff --git a/gcc/testsuite/c-c++-common/gomp/masked-2.c b/gcc/testsuite/c-c++-common/gomp/masked-2.c new file mode 100644 index 0000000..7230c82 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/masked-2.c @@ -0,0 +1,11 @@ +void bar (void); +struct S { int s; }; + +void +foo (float f, struct S s) +{ + #pragma omp masked filter (0.0) /* { dg-error "integral|integer" } */ + bar (); + #pragma omp masked filter (s) /* { dg-error "integral|integer" } */ + bar (); +} diff --git a/gcc/testsuite/c-c++-common/gomp/masked-combined-1.c b/gcc/testsuite/c-c++-common/gomp/masked-combined-1.c new file mode 100644 index 0000000..0b3ff58 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/masked-combined-1.c @@ -0,0 +1,37 @@ +void bar (int *); + +void +foo (int *a, int f) +{ + int i, j, k, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0; + #pragma omp parallel masked default(none) private (k) filter (f) firstprivate (f) + bar (&k); + #pragma omp parallel masked default(none) private (k) + bar (&k); + #pragma omp parallel default(none) firstprivate(a, f) shared(x, y, z) + { + #pragma omp masked taskloop reduction (+:x) default(none) firstprivate(a) filter (f) + for (i = 0; i < 64; i++) + x += a[i]; + #pragma omp masked taskloop simd reduction (+:y) default(none) firstprivate(a) private (i) filter (f) + for (i = 0; i < 64; i++) + y += a[i]; + #pragma omp masked taskloop simd reduction (+:y) default(none) firstprivate(a) private (i) + for (i = 0; i < 64; i++) + y += a[i]; + #pragma omp masked taskloop simd collapse(2) reduction (+:z) default(none) firstprivate(a) private (i, j) filter (f) + for (j = 0; j < 1; j++) + for (i = 0; i < 64; ++i) + z += a[i]; + } + #pragma omp parallel masked taskloop reduction (+:u) default(none) firstprivate(a, f) filter (f) + for (i = 0; i < 64; i++) + u += a[i]; + #pragma omp parallel masked taskloop simd reduction (+:v) default(none) firstprivate(a, f) filter (f) + for (i = 0; i < 64; i++) + v += a[i]; + #pragma omp parallel masked taskloop simd collapse(2) reduction (+:w) default(none) firstprivate(a, f) filter (f) + for (j = 0; j < 1; j++) + for (i = 0; i < 64; ++i) + w += a[i]; +} diff --git a/gcc/testsuite/c-c++-common/gomp/masked-combined-2.c b/gcc/testsuite/c-c++-common/gomp/masked-combined-2.c new file mode 100644 index 0000000..1d63969 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/masked-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 masked taskloop in_reduction(+:r) /* { dg-error "'in_reduction' is not valid for '#pragma omp parallel masked taskloop'" } */ + for (i = 0; i < 64; i++) + r += a[i]; + #pragma omp taskgroup task_reduction(+:s) + #pragma omp parallel masked taskloop simd in_reduction(+:s) /* { dg-error "'in_reduction' is not valid for '#pragma omp parallel masked taskloop simd'" } */ + for (i = 0; i < 64; i++) + s += a[i]; +} diff --git a/gcc/testsuite/g++.dg/gomp/attrs-1.C b/gcc/testsuite/g++.dg/gomp/attrs-1.C index 5c7007b..c348375 100644 --- a/gcc/testsuite/g++.dg/gomp/attrs-1.C +++ b/gcc/testsuite/g++.dg/gomp/attrs-1.C @@ -348,6 +348,10 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s, private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) copyin(t) allocate (f))]] ; + [[omp::directive (parallel masked + private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) reduction(+:r) + num_threads (nth) proc_bind(spread) copyin(t) allocate (f) filter (d))]] + ; [[omp::directive (parallel private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) copyin(t) allocate (f))]] @@ -358,7 +362,15 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s, reduction(default, +:r) in_reduction(+:r2) allocate (f)))]] for (int i = 0; i < 64; i++) ll++; + [[omp::sequence (directive (taskgroup task_reduction (+:r2) allocate (r2)), + omp::directive (masked 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) allocate (f) filter (d)))]] + for (int i = 0; i < 64; i++) + ll++; [[omp::directive (master)]]; + [[omp::directive (masked)]]; + [[omp::directive (masked filter (d))]]; [[omp::sequence (omp::directive (taskgroup task_reduction (+:r2) allocate (r2)), directive (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) @@ -366,23 +378,47 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s, order(concurrent) allocate (f)))]] for (int i = 0; i < 64; i++) ll++; + [[omp::sequence (omp::directive (taskgroup task_reduction (+:r2) allocate (r2)), + directive (masked 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) + order(concurrent) allocate (f) filter (d)))]] + for (int i = 0; i < 64; i++) + ll++; [[omp::directive (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) allocate (f))]] for (int i = 0; i < 64; i++) ll++; + [[omp::directive (parallel masked 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) allocate (f) filter (d))]] + for (int i = 0; i < 64; i++) + ll++; [[omp::directive (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) order(concurrent) allocate (f))]] for (int i = 0; i < 64; i++) ll++; + [[omp::directive (parallel masked 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) + order(concurrent) allocate (f) filter (d))]] + for (int i = 0; i < 64; i++) + ll++; [[omp::sequence (directive (taskgroup task_reduction (+:r2) allocate (r2)), directive (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++; + [[omp::sequence (directive (taskgroup task_reduction (+:r2) allocate (r2)), + directive (masked 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) filter (d)))]] + for (int i = 0; i < 64; i++) + ll++; [[omp::sequence (omp::directive (taskgroup task_reduction (+:r2) allocate (r2)), omp::directive (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) @@ -390,17 +426,35 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s, order(concurrent) allocate (f)))]] for (int i = 0; i < 64; i++) ll++; + [[omp::sequence (omp::directive (taskgroup task_reduction (+:r2) allocate (r2)), + omp::directive (masked 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) + order(concurrent) allocate (f) filter (d)))]] + for (int i = 0; i < 64; i++) + ll++; [[omp::directive (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) allocate (f))]] for (int i = 0; i < 64; i++) ll++; + [[omp::directive (parallel masked 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) allocate (f) filter (d))]] + for (int i = 0; i < 64; i++) + ll++; [[omp::directive (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) order(concurrent) allocate (f))]] for (int i = 0; i < 64; i++) ll++; + [[omp::directive (parallel masked 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) + order(concurrent) allocate (f) filter (d))]] + for (int i = 0; i < 64; i++) + ll++; [[omp::directive (loop bind(thread) order(concurrent) private (p) lastprivate (l) collapse(1) reduction(+:r))]] for (l = 0; l < 64; ++l) diff --git a/gcc/testsuite/g++.dg/gomp/attrs-2.C b/gcc/testsuite/g++.dg/gomp/attrs-2.C index 1b59abd..b2fba21 100644 --- a/gcc/testsuite/g++.dg/gomp/attrs-2.C +++ b/gcc/testsuite/g++.dg/gomp/attrs-2.C @@ -348,6 +348,10 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s, private (p),firstprivate (f),if (parallel: i2),default(shared),shared(s),reduction(+:r), num_threads (nth),proc_bind(spread),copyin(t),allocate (f))]] ; + [[omp::directive (parallel masked, + private (p),firstprivate (f),if (parallel: i2),default(shared),shared(s),reduction(+:r), + num_threads (nth),proc_bind(spread),copyin(t),allocate (f),filter(d))]] + ; [[omp::directive (parallel, private (p),firstprivate (f),if (parallel: i2),default(shared),shared(s),reduction(+:r), num_threads (nth),proc_bind(spread),copyin(t),allocate (f))]] @@ -358,7 +362,15 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s, reduction(default, +:r),in_reduction(+:r2),allocate (f)))]] for (int i = 0; i < 64; i++) ll++; + [[using omp:sequence (directive (taskgroup, task_reduction (+:r2),allocate (r2)), + omp::directive (masked 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),allocate (f),filter(d)))]] + for (int i = 0; i < 64; i++) + ll++; [[using omp:directive (master)]]; + [[using omp:directive (masked)]]; + [[using omp:directive (masked,filter(d))]]; [[omp::sequence (omp::directive (taskgroup task_reduction (+:r2),allocate (r2)), directive (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), @@ -366,23 +378,47 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s, order(concurrent),allocate (f)))]] for (int i = 0; i < 64; i++) ll++; + [[omp::sequence (omp::directive (taskgroup task_reduction (+:r2),allocate (r2)), + directive (masked 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), + order(concurrent),allocate (f),filter(d)))]] + for (int i = 0; i < 64; i++) + ll++; [[omp::directive (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),allocate (f))]] for (int i = 0; i < 64; i++) ll++; + [[omp::directive (parallel masked 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),allocate (f),filter(d))]] + for (int i = 0; i < 64; i++) + ll++; [[omp::directive (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), order(concurrent),allocate (f))]] for (int i = 0; i < 64; i++) ll++; + [[omp::directive (parallel masked 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), + order(concurrent),allocate (f),filter(d))]] + for (int i = 0; i < 64; i++) + ll++; [[omp::sequence (directive (taskgroup,task_reduction (+:r2),allocate (r2)), directive (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++; + [[omp::sequence (directive (taskgroup,task_reduction (+:r2),allocate (r2)), + directive (masked 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),filter(d)))]] + for (int i = 0; i < 64; i++) + ll++; [[omp::sequence (omp::directive (taskgroup,task_reduction (+:r2),allocate (r2)), omp::directive (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), @@ -390,17 +426,35 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s, order(concurrent),allocate (f)))]] for (int i = 0; i < 64; i++) ll++; + [[omp::sequence (omp::directive (taskgroup,task_reduction (+:r2),allocate (r2)), + omp::directive (masked 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), + order(concurrent),allocate (f),filter(d)))]] + for (int i = 0; i < 64; i++) + ll++; [[omp::directive (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),allocate (f))]] for (int i = 0; i < 64; i++) ll++; + [[omp::directive (parallel masked 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),allocate (f),filter(d))]] + for (int i = 0; i < 64; i++) + ll++; [[omp::directive (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), order(concurrent),allocate (f))]] for (int i = 0; i < 64; i++) ll++; + [[omp::directive (parallel masked 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), + order(concurrent),allocate (f),filter(d))]] + for (int i = 0; i < 64; i++) + ll++; [[omp::directive (loop, bind(thread),order(concurrent), private (p),lastprivate (l),collapse(1),reduction(+:r))]] for (l = 0; l < 64; ++l) diff --git a/gcc/testsuite/g++.dg/gomp/block-11.C b/gcc/testsuite/g++.dg/gomp/block-11.C index c280006..cf4b0d3 100644 --- a/gcc/testsuite/g++.dg/gomp/block-11.C +++ b/gcc/testsuite/g++.dg/gomp/block-11.C @@ -1,3 +1,21 @@ +// { dg-do compile } + +void foo() +{ + #pragma omp masked + { + goto bad1; // { dg-message "from here" } + } + + #pragma omp masked filter(1) + { + bad1: // { dg-error "jump" } + // { dg-message "exits OpenMP" "" { target *-*-* } .-1 } + return; // { dg-error "invalid exit" } + } +} + +// { dg-message "error: invalid branch to/from OpenMP structured block" "" { target *-*-* } 7 } /* PR c++/24516 */ /* { dg-do compile } */ diff --git a/gcc/testsuite/g++.dg/gomp/tpl-masked-1.C b/gcc/testsuite/g++.dg/gomp/tpl-masked-1.C new file mode 100644 index 0000000..8574861 --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/tpl-masked-1.C @@ -0,0 +1,21 @@ +// { dg-do compile } +// { dg-options "-fopenmp -fdump-tree-gimple" } + +int i; + +template <typename T> void f1 (bool p, T t) +{ + if (p) + { + #pragma omp masked filter (t) + i++; + } +} + +void f2 () +{ + f1<int> (true, 0); + f1<long> (true, 0L); +} + +// { dg-final { scan-tree-dump-times "#pragma omp masked" 2 "gimple" } } diff --git a/gcc/testsuite/gcc.dg/gomp/nesting-1.c b/gcc/testsuite/gcc.dg/gomp/nesting-1.c index 52fcda7..4a471c8 100644 --- a/gcc/testsuite/gcc.dg/gomp/nesting-1.c +++ b/gcc/testsuite/gcc.dg/gomp/nesting-1.c @@ -19,8 +19,10 @@ f1 (void) } #pragma omp single /* { dg-error "may not be closely nested" } */ ; - #pragma omp master /* { dg-error "may not be closely nested" } */ - ; + #pragma omp master /* { dg-error "may not be closely nested" } */ + ; + #pragma omp masked /* { dg-error "may not be closely nested" } */ + ; #pragma omp barrier /* { dg-error "may not be closely nested" } */ } #pragma omp sections @@ -50,6 +52,11 @@ f1 (void) } #pragma omp sections { + #pragma omp masked /* { dg-error "may not be closely nested" } */ + ; + } + #pragma omp sections + { #pragma omp section ; } @@ -81,6 +88,9 @@ f1 (void) #pragma omp section #pragma omp master /* { dg-error "may not be closely nested" } */ ; + #pragma omp section + #pragma omp masked /* { dg-error "may not be closely nested" } */ + ; } #pragma omp single { @@ -97,6 +107,8 @@ f1 (void) ; #pragma omp master /* { dg-error "may not be closely nested" } */ ; + #pragma omp masked /* { dg-error "may not be closely nested" } */ + ; #pragma omp barrier /* { dg-error "may not be closely nested" } */ } #pragma omp master @@ -116,6 +128,23 @@ f1 (void) ; #pragma omp barrier /* { dg-error "may not be closely nested" } */ } + #pragma omp masked filter (1) + { + #pragma omp for /* { dg-error "may not be closely nested" } */ + for (j = 0; j < 3; j++) + ; + #pragma omp sections /* { dg-error "may not be closely nested" } */ + { + ; + #pragma omp section + ; + } + #pragma omp single /* { dg-error "may not be closely nested" } */ + ; + #pragma omp master + ; + #pragma omp barrier /* { dg-error "may not be closely nested" } */ + } #pragma omp task { #pragma omp for /* { dg-error "may not be closely nested" } */ @@ -131,6 +160,8 @@ f1 (void) ; #pragma omp master /* { dg-error "may not be closely nested" } */ ; + #pragma omp masked /* { dg-error "may not be closely nested" } */ + ; #pragma omp barrier /* { dg-error "may not be closely nested" } */ } #pragma omp parallel @@ -148,6 +179,8 @@ f1 (void) ; #pragma omp master ; + #pragma omp masked + ; #pragma omp barrier } } @@ -171,6 +204,8 @@ f2 (void) ; #pragma omp master ; + #pragma omp masked + ; #pragma omp barrier /* { dg-error "may not be closely nested" } */ } } diff --git a/gcc/testsuite/gfortran.dg/goacc/host_data-tree.f95 b/gcc/testsuite/gfortran.dg/goacc/host_data-tree.f95 index 558e800..e575890 100644 --- a/gcc/testsuite/gfortran.dg/goacc/host_data-tree.f95 +++ b/gcc/testsuite/gfortran.dg/goacc/host_data-tree.f95 @@ -12,12 +12,12 @@ program test !$acc host_data use_device(p) if (p == 42) ! { dg-final { scan-tree-dump-times "(?n)D\\.\[0-9\]+ = \\*p == 42;$" 1 "original" } } ! { dg-final { scan-tree-dump-times "(?n)#pragma acc host_data use_device_ptr\\(p\\) if\\(D\\.\[0-9\]+\\)$" 1 "original" } } - ! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_host_data use_device_ptr\\(p\\) if\\(D\\.\[0-9\]+\\)$" 1 "gimple" } } + ! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_host_data use_device_ptr\\(p\\) if\\((?:D\\.|_)\[0-9\]+\\)$" 1 "gimple" } } !$acc end host_data !$acc host_data use_device(p) if_present if (p == 43) ! { dg-final { scan-tree-dump-times "(?n)D\\.\[0-9\]+ = \\*p == 43;$" 1 "original" } } ! { dg-final { scan-tree-dump-times "(?n)#pragma acc host_data use_device_ptr\\(p\\) if\\(D\\.\[0-9\]+\\) if_present$" 1 "original" } } - ! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_host_data use_device_ptr\\(if_present:p\\) if\\(D\\.\[0-9\]+\\) if_present$" 1 "gimple" } } + ! { dg-final { scan-tree-dump-times "(?n)#pragma omp target oacc_host_data use_device_ptr\\(if_present:p\\) if\\((?:D\\.|_)\[0-9\]+\\) if_present$" 1 "gimple" } } !$acc end host_data end program test diff --git a/gcc/testsuite/gfortran.dg/goacc/kernels-tree.f95 b/gcc/testsuite/gfortran.dg/goacc/kernels-tree.f95 index 63ef7e1..688ed0a 100644 --- a/gcc/testsuite/gfortran.dg/goacc/kernels-tree.f95 +++ b/gcc/testsuite/gfortran.dg/goacc/kernels-tree.f95 @@ -37,5 +37,5 @@ end program test ! { dg-final { scan-tree-dump-times "map\\(force_deviceptr:u\\)" 1 "original" } } -! { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_data_kernels if\(D\.[0-9]+\)$} 1 "omp_oacc_kernels_decompose" } } -! { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_parallel_kernels_gang_single num_gangs\(1\) if\(D\.[0-9]+\) async\(-1\)$} 1 "omp_oacc_kernels_decompose" } } +! { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_data_kernels if\((?:D\.|_)[0-9]+\)$} 1 "omp_oacc_kernels_decompose" } } +! { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_parallel_kernels_gang_single num_gangs\(1\) if\((?:D\.|_)[0-9]+\) async\(-1\)$} 1 "omp_oacc_kernels_decompose" } } diff --git a/gcc/tree-core.h b/gcc/tree-core.h index 9a1aa9a..9e901ce 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -476,6 +476,9 @@ enum omp_clause_code { /* OpenMP clause: bind (binding). */ OMP_CLAUSE_BIND, + /* OpenMP clause: filter (integer-expression). */ + OMP_CLAUSE_FILTER, + /* Internally used only clause, holding SIMD uid. */ OMP_CLAUSE__SIMDUID_, diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 8e6cdd3..4ba48e0 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1658,6 +1658,12 @@ remap_gimple_stmt (gimple *stmt, copy_body_data *id) copy = gimple_build_omp_master (s1); break; + case GIMPLE_OMP_MASKED: + s1 = remap_gimple_seq (gimple_omp_body (stmt), id); + copy = gimple_build_omp_masked + (s1, gimple_omp_masked_clauses (stmt)); + break; + case GIMPLE_OMP_TASKGROUP: s1 = remap_gimple_seq (gimple_omp_body (stmt), id); copy = gimple_build_omp_taskgroup @@ -4544,6 +4550,7 @@ estimate_num_insns (gimple *stmt, eni_weights *weights) case GIMPLE_OMP_TASK: case GIMPLE_OMP_CRITICAL: case GIMPLE_OMP_MASTER: + case GIMPLE_OMP_MASKED: case GIMPLE_OMP_TASKGROUP: case GIMPLE_OMP_ORDERED: case GIMPLE_OMP_SCAN: diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c index cc59526..d2b3969 100644 --- a/gcc/tree-nested.c +++ b/gcc/tree-nested.c @@ -1376,6 +1376,7 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) case OMP_CLAUSE_GRAINSIZE: case OMP_CLAUSE_NUM_TASKS: case OMP_CLAUSE_HINT: + case OMP_CLAUSE_FILTER: case OMP_CLAUSE_NUM_GANGS: case OMP_CLAUSE_NUM_WORKERS: case OMP_CLAUSE_VECTOR_LENGTH: @@ -1785,6 +1786,7 @@ convert_nonlocal_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p, case GIMPLE_OMP_SECTION: case GIMPLE_OMP_MASTER: + case GIMPLE_OMP_MASKED: case GIMPLE_OMP_ORDERED: case GIMPLE_OMP_SCAN: walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op, @@ -2154,6 +2156,7 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi) case OMP_CLAUSE_GRAINSIZE: case OMP_CLAUSE_NUM_TASKS: case OMP_CLAUSE_HINT: + case OMP_CLAUSE_FILTER: case OMP_CLAUSE_NUM_GANGS: case OMP_CLAUSE_NUM_WORKERS: case OMP_CLAUSE_VECTOR_LENGTH: @@ -2518,6 +2521,7 @@ convert_local_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p, case GIMPLE_OMP_SECTION: case GIMPLE_OMP_MASTER: + case GIMPLE_OMP_MASKED: case GIMPLE_OMP_ORDERED: case GIMPLE_OMP_SCAN: walk_body (convert_local_reference_stmt, convert_local_reference_op, @@ -3028,6 +3032,7 @@ convert_gimple_call (gimple_stmt_iterator *gsi, bool *handled_ops_p, case GIMPLE_OMP_SECTION: case GIMPLE_OMP_SINGLE: case GIMPLE_OMP_MASTER: + case GIMPLE_OMP_MASKED: case GIMPLE_OMP_TASKGROUP: case GIMPLE_OMP_ORDERED: case GIMPLE_OMP_SCAN: diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c index 31f886f..5ac4034 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -1085,6 +1085,13 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags) pp_right_paren (pp); break; + case OMP_CLAUSE_FILTER: + pp_string (pp, "filter("); + dump_generic_node (pp, OMP_CLAUSE_FILTER_EXPR (clause), + spc, flags, false); + pp_right_paren (pp); + break; + case OMP_CLAUSE_DEFAULTMAP: pp_string (pp, "defaultmap("); switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (clause)) @@ -3586,6 +3593,11 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags, pp_string (pp, "#pragma omp master"); goto dump_omp_body; + case OMP_MASKED: + pp_string (pp, "#pragma omp masked"); + dump_omp_clauses (pp, OMP_MASKED_CLAUSES (node), spc, flags); + goto dump_omp_body; + case OMP_TASKGROUP: pp_string (pp, "#pragma omp taskgroup"); dump_omp_clauses (pp, OMP_TASKGROUP_CLAUSES (node), spc, flags); @@ -350,6 +350,7 @@ unsigned const char omp_clause_num_ops[] = 0, /* OMP_CLAUSE_DEFAULTMAP */ 0, /* OMP_CLAUSE_ORDER */ 0, /* OMP_CLAUSE_BIND */ + 1, /* OMP_CLAUSE_FILTER */ 1, /* OMP_CLAUSE__SIMDUID_ */ 0, /* OMP_CLAUSE__SIMT_ */ 0, /* OMP_CLAUSE_INDEPENDENT */ @@ -438,6 +439,7 @@ const char * const omp_clause_code_name[] = "defaultmap", "order", "bind", + "filter", "_simduid_", "_simt_", "independent", @@ -11126,6 +11128,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, case OMP_CLAUSE_GRAINSIZE: case OMP_CLAUSE_NUM_TASKS: case OMP_CLAUSE_HINT: + case OMP_CLAUSE_FILTER: case OMP_CLAUSE_TO_DECLARE: case OMP_CLAUSE_LINK: case OMP_CLAUSE_DETACH: diff --git a/gcc/tree.def b/gcc/tree.def index eda050b..ff8b5e6 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -1218,6 +1218,11 @@ DEFTREECODE (OMP_SINGLE, "omp_single", tcc_statement, 2) Operand 1: OMP_SINGLE_CLAUSES: List of clauses. */ DEFTREECODE (OMP_TASKGROUP, "omp_taskgroup", tcc_statement, 2) +/* OpenMP - #pragma omp masked + Operand 0: OMP_MASKED_BODY: Masked section body. + Operand 1: OMP_MASKED_CLAUSES: List of clauses. */ +DEFTREECODE (OMP_MASKED, "omp_masked", tcc_statement, 2) + /* OpenMP - #pragma omp scan Operand 0: OMP_SCAN_BODY: Scan body. Operand 1: OMP_SCAN_CLAUSES: List of clauses. */ @@ -1429,6 +1429,9 @@ class auto_suppress_location_wrappers #define OMP_MASTER_BODY(NODE) TREE_OPERAND (OMP_MASTER_CHECK (NODE), 0) +#define OMP_MASKED_BODY(NODE) TREE_OPERAND (OMP_MASKED_CHECK (NODE), 0) +#define OMP_MASKED_CLAUSES(NODE) TREE_OPERAND (OMP_MASKED_CHECK (NODE), 1) + #define OMP_TASKGROUP_BODY(NODE) TREE_OPERAND (OMP_TASKGROUP_CHECK (NODE), 0) #define OMP_TASKGROUP_CLAUSES(NODE) \ TREE_OPERAND (OMP_TASKGROUP_CHECK (NODE), 1) @@ -1508,6 +1511,11 @@ class auto_suppress_location_wrappers #define OMP_MASTER_COMBINED(NODE) \ (OMP_MASTER_CHECK (NODE)->base.private_flag) +/* True on an OMP_MASKED statement if it represents an explicit + combined masked constructs. */ +#define OMP_MASKED_COMBINED(NODE) \ + (OMP_MASKED_CHECK (NODE)->base.private_flag) + /* Memory order for OMP_ATOMIC*. */ #define OMP_ATOMIC_MEMORY_ORDER(NODE) \ (TREE_RANGE_CHECK (NODE, OMP_ATOMIC, \ @@ -1592,6 +1600,8 @@ class auto_suppress_location_wrappers OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_NUM_TASKS), 0) #define OMP_CLAUSE_HINT_EXPR(NODE) \ OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_HINT), 0) +#define OMP_CLAUSE_FILTER_EXPR(NODE) \ + OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_FILTER), 0) #define OMP_CLAUSE_GRAINSIZE_EXPR(NODE) \ OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_GRAINSIZE),0) diff --git a/libgomp/testsuite/libgomp.c-c++-common/masked-1.c b/libgomp/testsuite/libgomp.c-c++-common/masked-1.c new file mode 100644 index 0000000..4ba259c --- /dev/null +++ b/libgomp/testsuite/libgomp.c-c++-common/masked-1.c @@ -0,0 +1,83 @@ +#include <omp.h> +#include <stdlib.h> + +void +foo (int x, int *a) +{ + #pragma omp masked + { + if (omp_get_thread_num () != 0) + abort (); + a[128]++; + } + #pragma omp masked filter (0) + { + if (omp_get_thread_num () != 0) + abort (); + a[129]++; + } + #pragma omp masked filter (7) + { + if (omp_get_thread_num () != 7) + abort (); + a[130]++; + } + #pragma omp masked filter (x) + { + if (omp_get_thread_num () != x) + abort (); + a[131]++; + } + #pragma omp masked taskloop simd filter (x) grainsize (12) simdlen (4) + for (int i = 0; i < 128; i++) + a[i] += i; +} + +int +main () +{ + int a[136] = {}; + #pragma omp parallel num_threads (4) + foo (4, a); + for (int i = 0; i < 128; i++) + if (a[i]) + abort (); + if (a[128] != 1 || a[129] != 1 || a[130] || a[131]) + abort (); + #pragma omp parallel num_threads (4) + foo (3, a); + for (int i = 0; i < 128; i++) + if (a[i] != i) + abort (); + if (a[128] != 2 || a[129] != 2 || a[130] || a[131] != 1) + abort (); + #pragma omp parallel num_threads (8) + foo (8, a); + for (int i = 0; i < 128; i++) + if (a[i] != i) + abort (); + if (a[128] != 3 || a[129] != 3 || a[130] != 1 || a[131] != 1) + abort (); + #pragma omp parallel num_threads (8) + foo (6, a); + for (int i = 0; i < 128; i++) + if (a[i] != 2 * i) + abort (); + if (a[128] != 4 || a[129] != 4 || a[130] != 2 || a[131] != 2) + abort (); + for (int i = 0; i < 8; i++) + a[i] = 0; + /* The filter expression can evaluate to different values in different threads. */ + #pragma omp parallel masked num_threads (8) filter (omp_get_thread_num () + 1) + a[omp_get_thread_num ()]++; + for (int i = 0; i < 8; i++) + if (a[i]) + abort (); + /* And multiple threads can be filtered. */ + #pragma omp parallel masked num_threads (8) filter (omp_get_thread_num () & ~1) + a[omp_get_thread_num ()]++; + for (int i = 0; i < 8; i++) + if (a[i] != !(i & 1)) + abort (); + return 0; +} |