aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/c-parser.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2019-07-20 13:21:42 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2019-07-20 13:21:42 +0200
commit554a530ff81870098572832eed8ca00b3593bb41 (patch)
tree7d7930d120a4adebe92eebe4c63a801388f5a6a5 /gcc/c/c-parser.c
parentb6339213ff68ac5a87b7fdda878f26b52d801b76 (diff)
downloadgcc-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.c143
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);