diff options
author | Jakub Jelinek <jakub@redhat.com> | 2019-07-20 13:21:42 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2019-07-20 13:21:42 +0200 |
commit | 554a530ff81870098572832eed8ca00b3593bb41 (patch) | |
tree | 7d7930d120a4adebe92eebe4c63a801388f5a6a5 /gcc/c/c-parser.c | |
parent | b6339213ff68ac5a87b7fdda878f26b52d801b76 (diff) | |
download | gcc-554a530ff81870098572832eed8ca00b3593bb41.zip gcc-554a530ff81870098572832eed8ca00b3593bb41.tar.gz gcc-554a530ff81870098572832eed8ca00b3593bb41.tar.bz2 |
tree.def (OMP_LOOP): New tree code.
* tree.def (OMP_LOOP): New tree code.
* tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_BIND.
(enum omp_clause_bind_kind): New enum.
(struct tree_omp_clause): Add subcode.bind_kind.
* tree.h (OMP_LOOP_CHECK): Rename to ...
(OMP_LOOPING_CHECK): ... this.
(OMP_FOR_BODY, OMP_FOR_CLAUSES, OMP_FOR_INIT, OMP_FOR_COND,
OMP_FOR_INCR, OMP_FOR_PRE_BODY, OMP_FOR_ORIG_DECLS): Use
OMP_LOOPING_CHECK instead of OMP_LOOP_CHECK.
(OMP_CLAUSE_BIND_KIND): Define.
* tree.c (omp_clause_num_ops, omp_clause_code_name): Add
bind clause entries.
(walk_tree_1): Handle OMP_CLAUSE_BIND.
* tree-pretty-print.c (dump_omp_clause): Likewise.
(dump_generic_node): Handle OMP_LOOP.
* gimplify.c (enum omp_region_type): Add ORT_IMPLICIT_TARGET.
(in_omp_construct): New variable.
(is_gimple_stmt): Handle OMP_LOOP.
(gimplify_scan_omp_clauses): For lastprivate don't set
check_non_private if code == OMP_LOOP. For reduction clause
on OMP_LOOP combined with parallel or teams propagate as shared
on the combined construct. Handle OMP_CLAUSE_BIND.
(gimplify_adjust_omp_clauses): Handle OMP_CLAUSE_BIND.
(gimplify_omp_for): Pass OMP_LOOP instead of OMP_{FOR,DISTRIBUTE}
for constructs from a loop construct to gimplify_scan_omp_clauses.
Don't predetermine iterator linear on OMP_SIMD from loop construct.
(replace_reduction_placeholders, gimplify_omp_loop): New functions.
(gimplify_omp_workshare): Use ORT_IMPLICIT_TARGET instead of trying
to match the implicit ORT_TARGET construct around whole body.
Temporarily clear in_omp_construct when processing body.
(gimplify_expr): Handle OMP_LOOP. For OMP_MASTER, OMP_TASKGROUP
etc. temporarily set in_omp_construct when processing body.
(gimplify_body): Create ORT_IMPLICIT_TARGET instead of ORT_TARGET.
* omp-low.c (struct omp_context): Add loop_p.
(build_outer_var_ref): Treat ctx->loop_p similarly to simd construct
in that the original var might be private.
(scan_sharing_clauses): Handle OMP_CLAUSE_BIND.
(check_omp_nesting_restrictions): Adjust nesting restrictions for
addition of loop construct.
(scan_omp_1_stmt): Allow setjmp inside of loop construct.
gcc/c-family/
* c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_LOOP.
(enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_BIND.
* c-pragma.c (omp_pragmas_simd): Add PRAGMA_OMP_LOOP entry.
* c-common.h (enum c_omp_clause_split): Add C_OMP_CLAUSE_SPLIT_LOOP.
* c-omp.c (c_omp_split_clauses): Add support for 4 new combined
constructs with the loop construct.
gcc/c/
* c-parser.c (c_parser_omp_clause_name): Handle bind clause.
(c_parser_omp_clause_bind): New function.
(c_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_BIND.
(OMP_LOOP_CLAUSE_MASK): Define.
(c_parser_omp_loop): New function.
(c_parser_omp_parallel, c_parser_omp_teams): Handle parsing of
loop combined with parallel or teams.
(c_parser_omp_construct): Handle PRAGMA_OMP_LOOP.
* c-typeck.c (c_finish_omp_clauses): Handle OMP_CLAUSE_BIND.
gcc/cp/
* cp-tree.h (OMP_FOR_GIMPLIFYING_P): Use OMP_LOOPING_CHECK
instead of OMP_LOOP_CHECK.
* parser.c (cp_parser_omp_clause_name): Handle bind clause.
(cp_parser_omp_clause_bind): New function.
(cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_BIND.
(OMP_LOOP_CLAUSE_MASK): Define.
(cp_parser_omp_loop): New function.
(cp_parser_omp_parallel, cp_parser_omp_teams): Handle parsing of
loop combined with parallel or teams.
(cp_parser_omp_construct): Handle PRAGMA_OMP_LOOP.
(cp_parser_pragma): Likewise.
* pt.c (tsubst_expr): Handle OMP_LOOP.
* semantics.c (finish_omp_clauses): Handle OMP_CLAUSE_BIND.
gcc/testsuite/
* c-c++-common/gomp/cancel-1.c: Adjust expected diagnostic wording.
* c-c++-common/gomp/clauses-1.c (foo, baz, bar): Add order(concurrent)
clause where allowed. Add combined constructs with loop with all
possible clauses.
(qux): New function.
* c-c++-common/gomp/loop-1.c: New test.
* c-c++-common/gomp/loop-2.c: New test.
* c-c++-common/gomp/loop-3.c: New test.
* c-c++-common/gomp/loop-4.c: New test.
* c-c++-common/gomp/loop-5.c: New test.
* c-c++-common/gomp/order-3.c: Adjust expected diagnostic wording.
* c-c++-common/gomp/simd-setjmp-1.c: New test.
* c-c++-common/gomp/teams-2.c: Adjust expected diagnostic wording.
libgomp/
* testsuite/libgomp.c-c++-common/loop-1.c: New test.
From-SVN: r273621
Diffstat (limited to 'gcc/c/c-parser.c')
-rw-r--r-- | gcc/c/c-parser.c | 143 |
1 files changed, 140 insertions, 3 deletions
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 1f83c24..6721049 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -11688,6 +11688,10 @@ c_parser_omp_clause_name (c_parser *parser) else if (!strcmp ("async", p)) result = PRAGMA_OACC_CLAUSE_ASYNC; break; + case 'b': + if (!strcmp ("bind", p)) + result = PRAGMA_OMP_CLAUSE_BIND; + break; case 'c': if (!strcmp ("collapse", p)) result = PRAGMA_OMP_CLAUSE_COLLAPSE; @@ -13507,6 +13511,45 @@ c_parser_omp_clause_order (c_parser *parser, tree list) } +/* OpenMP 5.0: + bind ( teams | parallel | thread ) */ + +static tree +c_parser_omp_clause_bind (c_parser *parser, tree list) +{ + location_t loc = c_parser_peek_token (parser)->location; + tree c; + const char *p; + enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD; + + matching_parens parens; + if (!parens.require_open (parser)) + return list; + if (!c_parser_next_token_is (parser, CPP_NAME)) + { + invalid: + c_parser_error (parser, + "expected %<teams%>, %<parallel%> or %<thread%>"); + parens.skip_until_found_close (parser); + return list; + } + p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); + if (strcmp (p, "teams") == 0) + kind = OMP_CLAUSE_BIND_TEAMS; + else if (strcmp (p, "parallel") == 0) + kind = OMP_CLAUSE_BIND_PARALLEL; + else if (strcmp (p, "thread") != 0) + goto invalid; + c_parser_consume_token (parser); + parens.skip_until_found_close (parser); + /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */ + c = build_omp_clause (loc, OMP_CLAUSE_BIND); + OMP_CLAUSE_BIND_KIND (c) = kind; + OMP_CLAUSE_CHAIN (c) = list; + return c; +} + + /* OpenMP 2.5: ordered @@ -15066,6 +15109,10 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask, switch (c_kind) { + case PRAGMA_OMP_CLAUSE_BIND: + clauses = c_parser_omp_clause_bind (parser, clauses); + c_name = "bind"; + break; case PRAGMA_OMP_CLAUSE_COLLAPSE: clauses = c_parser_omp_clause_collapse (parser, clauses); c_name = "collapse"; @@ -17248,6 +17295,46 @@ omp_split_clauses (location_t loc, enum tree_code code, cclauses[i] = c_finish_omp_clauses (cclauses[i], C_ORT_OMP); } +/* OpenMP 5.0: + #pragma omp loop loop-clause[optseq] new-line + for-loop + + LOC is the location of the #pragma token. +*/ + +#define OMP_LOOP_CLAUSE_MASK \ + ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER)) + +static tree +c_parser_omp_loop (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, " loop"); + mask |= OMP_LOOP_CLAUSE_MASK; + + clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); + if (cclauses) + { + omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses); + clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP]; + } + + block = c_begin_compound_stmt (true); + ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p); + block = c_end_compound_stmt (loc, block, true); + add_stmt (block); + + return ret; +} + /* OpenMP 4.0: #pragma omp simd simd-clause[optseq] new-line for-loop @@ -17713,10 +17800,10 @@ c_parser_omp_parallel (location_t loc, c_parser *parser, c_parser_skip_to_pragma_eol (parser); return NULL_TREE; } - else if (cclauses == NULL && c_parser_next_token_is (parser, CPP_NAME)) + else if (c_parser_next_token_is (parser, CPP_NAME)) { const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); - if (strcmp (p, "master") == 0) + if (cclauses == NULL && strcmp (p, "master") == 0) { tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; cclauses = cclauses_buf; @@ -17736,12 +17823,34 @@ c_parser_omp_parallel (location_t loc, c_parser *parser, return ret; return stmt; } + else if (strcmp (p, "loop") == 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_loop (loc, parser, p_name, mask, cclauses, + if_p); + block = c_begin_omp_parallel (); + tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, + if_p); + stmt + = c_finish_omp_parallel (loc, + cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL], + block); + if (ret == NULL_TREE) + return ret; + OMP_PARALLEL_COMBINED (stmt) = 1; + 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) + else if (cclauses == NULL && strcmp (p, "sections") == 0) { tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; cclauses = cclauses_buf; @@ -18121,6 +18230,30 @@ c_parser_omp_teams (location_t loc, c_parser *parser, SET_EXPR_LOCATION (ret, loc); return add_stmt (ret); } + else if (strcmp (p, "loop") == 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_loop (loc, parser, p_name, mask, cclauses, + if_p); + block = c_begin_omp_parallel (); + ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p); + block = c_end_compound_stmt (loc, block, true); + if (ret == NULL) + return ret; + clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS]; + ret = make_node (OMP_TEAMS); + TREE_TYPE (ret) = void_type_node; + OMP_TEAMS_CLAUSES (ret) = clauses; + OMP_TEAMS_BODY (ret) = block; + OMP_TEAMS_COMBINED (ret) = 1; + SET_EXPR_LOCATION (ret, loc); + return add_stmt (ret); + } } if (!flag_openmp) /* flag_openmp_simd */ { @@ -19670,6 +19803,10 @@ c_parser_omp_construct (c_parser *parser, bool *if_p) strcpy (p_name, "#pragma omp"); stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p); break; + case PRAGMA_OMP_LOOP: + strcpy (p_name, "#pragma omp"); + stmt = c_parser_omp_loop (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); |