@@ -9751,8 +9751,7 @@ c_parser_pragma (c_parser *parser, enum
return false;
case PRAGMA_OMP_ORDERED:
- c_parser_omp_ordered (parser, context);
- return false;
+ return c_parser_omp_ordered (parser, context);
case PRAGMA_IVDEP:
c_parser_consume_pragma (parser);
@@ -13663,14 +13662,16 @@ c_parser_omp_ordered (c_parser *parser,
= c_parser_omp_all_clauses (parser,
OMP_ORDERED_DEPEND_CLAUSE_MASK,
"#pragma omp ordered");
- return c_finish_omp_ordered (loc, clauses, NULL_TREE);
+ c_finish_omp_ordered (loc, clauses, NULL_TREE);
+ return false;
}
}
tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
"#pragma omp ordered");
- return c_finish_omp_ordered (loc, clauses,
- c_parser_omp_structured_block (parser));
+ c_finish_omp_ordered (loc, clauses,
+ c_parser_omp_structured_block (parser));
+ return true;
}
/* OpenMP 2.5:
@@ -14242,7 +14243,9 @@ c_parser_omp_target_data (location_t loc
( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
static bool
c_parser_omp_target_update (location_t loc, c_parser *parser,
@@ -14512,13 +14515,13 @@ c_parser_omp_target (c_parser *parser, e
{
c_parser_consume_token (parser);
c_parser_omp_target_enter_data (loc, parser, context);
- return true;
+ return false;
}
else if (strcmp (p, "exit") == 0)
{
c_parser_consume_token (parser);
c_parser_omp_target_exit_data (loc, parser, context);
- return true;
+ return false;
}
else if (strcmp (p, "update") == 0)
{
@@ -15212,6 +15215,9 @@ c_parser_omp_declare (c_parser *parser,
/* OpenMP 4.1:
#pragma omp taskloop taskloop-clause[optseq] new-line
+ for-loop
+
+ #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
for-loop */
#define OMP_TASKLOOP_CLAUSE_MASK \
@@ -27631,6 +27631,10 @@ cp_parser_omp_clause_name (cp_parser *pa
else if (!strcmp ("from", p))
result = PRAGMA_OMP_CLAUSE_FROM;
break;
+ case 'g':
+ if (!strcmp ("grainsize", p))
+ result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
+ break;
case 'h':
if (!strcmp ("host", p))
result = PRAGMA_OACC_CLAUSE_HOST;
@@ -27654,7 +27658,9 @@ cp_parser_omp_clause_name (cp_parser *pa
result = PRAGMA_CILK_CLAUSE_MASK;
break;
case 'n':
- if (!strcmp ("notinbranch", p))
+ if (!strcmp ("nogroup", p))
+ result = PRAGMA_OMP_CLAUSE_NOGROUP;
+ else if (!strcmp ("notinbranch", p))
result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
else if (!strcmp ("nowait", p))
result = PRAGMA_OMP_CLAUSE_NOWAIT;
@@ -27662,6 +27668,8 @@ cp_parser_omp_clause_name (cp_parser *pa
result = PRAGMA_CILK_CLAUSE_NOMASK;
else if (!strcmp ("num_gangs", p))
result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
+ else if (!strcmp ("num_tasks", p))
+ result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
else if (!strcmp ("num_teams", p))
result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
else if (!strcmp ("num_threads", p))
@@ -27690,6 +27698,8 @@ cp_parser_omp_clause_name (cp_parser *pa
else if (!strcmp ("present_or_create", p)
|| !strcmp ("pcreate", p))
result = PRAGMA_OACC_CLAUSE_PRESENT_OR_CREATE;
+ else if (!strcmp ("priority", p))
+ result = PRAGMA_OMP_CLAUSE_PRIORITY;
else if (!strcmp ("proc_bind", p))
result = PRAGMA_OMP_CLAUSE_PROC_BIND;
break;
@@ -27708,6 +27718,8 @@ cp_parser_omp_clause_name (cp_parser *pa
result = PRAGMA_OACC_CLAUSE_SELF;
else if (!strcmp ("shared", p))
result = PRAGMA_OMP_CLAUSE_SHARED;
+ else if (!strcmp ("simd", p))
+ result = PRAGMA_OMP_CLAUSE_SIMD;
else if (!strcmp ("simdlen", p))
result = PRAGMA_OMP_CLAUSE_SIMDLEN;
break;
@@ -27716,6 +27728,8 @@ cp_parser_omp_clause_name (cp_parser *pa
result = PRAGMA_OMP_CLAUSE_TASKGROUP;
else if (!strcmp ("thread_limit", p))
result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
+ else if (!strcmp ("threads", p))
+ result = PRAGMA_OMP_CLAUSE_THREADS;
else if (!strcmp ("to", p))
result = PRAGMA_OMP_CLAUSE_TO;
break;
@@ -28400,6 +28414,96 @@ cp_parser_omp_clause_num_threads (cp_par
return c;
}
+/* OpenMP 4.1:
+ num_tasks ( expression ) */
+
+static tree
+cp_parser_omp_clause_num_tasks (cp_parser *parser, tree list,
+ location_t location)
+{
+ tree t, c;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ t = cp_parser_expression (parser);
+
+ if (t == error_mark_node
+ || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS,
+ "num_tasks", location);
+
+ c = build_omp_clause (location, OMP_CLAUSE_NUM_TASKS);
+ OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
+ OMP_CLAUSE_CHAIN (c) = list;
+
+ return c;
+}
+
+/* OpenMP 4.1:
+ grainsize ( expression ) */
+
+static tree
+cp_parser_omp_clause_grainsize (cp_parser *parser, tree list,
+ location_t location)
+{
+ tree t, c;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ t = cp_parser_expression (parser);
+
+ if (t == error_mark_node
+ || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE,
+ "grainsize", location);
+
+ c = build_omp_clause (location, OMP_CLAUSE_GRAINSIZE);
+ OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
+ OMP_CLAUSE_CHAIN (c) = list;
+
+ return c;
+}
+
+/* OpenMP 4.1:
+ priority ( expression ) */
+
+static tree
+cp_parser_omp_clause_priority (cp_parser *parser, tree list,
+ location_t location)
+{
+ tree t, c;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ t = cp_parser_expression (parser);
+
+ if (t == error_mark_node
+ || !cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE,
+ "priority", location);
+
+ c = build_omp_clause (location, OMP_CLAUSE_PRIORITY);
+ OMP_CLAUSE_PRIORITY_EXPR (c) = t;
+ OMP_CLAUSE_CHAIN (c) = list;
+
+ return c;
+}
+
/* OpenACC:
num_workers ( expression ) */
@@ -28438,19 +28542,49 @@ cp_parser_omp_clause_num_workers (cp_par
}
/* OpenMP 2.5:
- ordered */
+ ordered
+
+ OpenMP 4.1:
+ ordered ( constant-expression ) */
static tree
-cp_parser_omp_clause_ordered (cp_parser * /*parser*/,
+cp_parser_omp_clause_ordered (cp_parser *parser,
tree list, location_t location)
{
- tree c;
+ tree c, num = NULL_TREE;
+ HOST_WIDE_INT n;
check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED,
"ordered", location);
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+ {
+ cp_lexer_consume_token (parser->lexer);
+
+ num = cp_parser_constant_expression (parser);
+
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ if (num == error_mark_node)
+ return list;
+ num = fold_non_dependent_expr (num);
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
+ || !tree_fits_shwi_p (num)
+ || (n = tree_to_shwi (num)) <= 0
+ || (int) n != n)
+ {
+ error_at (location,
+ "ordered argument needs positive constant integer "
+ "expression");
+ return list;
+ }
+ }
+
c = build_omp_clause (location, OMP_CLAUSE_ORDERED);
- OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
+ OMP_CLAUSE_ORDERED_EXPR (c) = num;
OMP_CLAUSE_CHAIN (c) = list;
return c;
}
@@ -28702,6 +28836,34 @@ cp_parser_omp_clause_cancelkind (cp_pars
return c;
}
+/* OpenMP 4.1:
+ nogroup */
+
+static tree
+cp_parser_omp_clause_nogroup (cp_parser * /*parser*/,
+ tree list, location_t location)
+{
+ check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup", location);
+ tree c = build_omp_clause (location, OMP_CLAUSE_NOGROUP);
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+}
+
+/* OpenMP 4.1:
+ simd
+ threads */
+
+static tree
+cp_parser_omp_clause_orderedkind (cp_parser * /*parser*/,
+ enum omp_clause_code code,
+ tree list, location_t location)
+{
+ check_no_duplicate_clause (list, code, omp_clause_code_name[code], location);
+ tree c = build_omp_clause (location, code);
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+}
+
/* OpenMP 4.0:
num_teams ( expression ) */
@@ -28900,10 +29062,16 @@ cp_parser_omp_clause_simdlen (cp_parser
depend ( depend-kind : variable-list )
depend-kind:
- in | out | inout */
+ in | out | inout
+
+ OpenMP 4.1:
+ depend ( depend-loop-kind [ : vec ] )
+
+ depend-loop-kind:
+ source | sink */
static tree
-cp_parser_omp_clause_depend (cp_parser *parser, tree list)
+cp_parser_omp_clause_depend (cp_parser *parser, tree list, location_t loc)
{
tree nlist, c;
enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INOUT;
@@ -28922,6 +29090,10 @@ cp_parser_omp_clause_depend (cp_parser *
kind = OMP_CLAUSE_DEPEND_INOUT;
else if (strcmp ("out", p) == 0)
kind = OMP_CLAUSE_DEPEND_OUT;
+ else if (strcmp ("source", p) == 0)
+ kind = OMP_CLAUSE_DEPEND_SOURCE;
+ else if (strcmp ("sink", p) == 0)
+ kind = OMP_CLAUSE_DEPEND_SINK;
else
goto invalid_kind;
}
@@ -28929,6 +29101,22 @@ cp_parser_omp_clause_depend (cp_parser *
goto invalid_kind;
cp_lexer_consume_token (parser->lexer);
+
+ if (kind == OMP_CLAUSE_DEPEND_SOURCE)
+ {
+ c = build_omp_clause (loc, OMP_CLAUSE_DEPEND);
+ OMP_CLAUSE_DEPEND_KIND (c) = kind;
+ OMP_CLAUSE_DECL (c) = NULL_TREE;
+ OMP_CLAUSE_CHAIN (c) = list;
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ return c;
+ }
+
+ /* FIXME: Handle OMP_CLAUSE_DEPEND_SINK. */
+
if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
goto resync_fail;
@@ -28954,17 +29142,46 @@ cp_parser_omp_clause_depend (cp_parser *
map ( variable-list )
map-kind:
- alloc | to | from | tofrom */
+ alloc | to | from | tofrom
+
+ OpenMP 4.1:
+ map-kind:
+ alloc | to | from | tofrom | delete
+
+ map ( always [,] map-kind: variable-list ) */
static tree
cp_parser_omp_clause_map (cp_parser *parser, tree list)
{
tree nlist, c;
enum gomp_map_kind kind = GOMP_MAP_TOFROM;
+ bool always = false;
if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
return list;
+ 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 ("always", p) == 0)
+ {
+ int nth = 2;
+ if (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_COMMA)
+ nth++;
+ if (cp_lexer_peek_nth_token (parser->lexer, nth)->type == CPP_NAME
+ && (cp_lexer_peek_nth_token (parser->lexer, nth + 1)->type
+ == CPP_COLON))
+ {
+ always = true;
+ cp_lexer_consume_token (parser->lexer);
+ if (nth == 3)
+ cp_lexer_consume_token (parser->lexer);
+ }
+ }
+ }
+
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
&& cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_COLON)
{
@@ -28979,6 +29196,8 @@ cp_parser_omp_clause_map (cp_parser *par
kind = GOMP_MAP_FROM;
else if (strcmp ("tofrom", p) == 0)
kind = GOMP_MAP_TOFROM;
+ else if (strcmp ("delete", p) == 0)
+ kind = GOMP_MAP_FORCE_DEALLOC;
else
{
cp_parser_error (parser, "invalid map kind");
@@ -28987,6 +29206,8 @@ cp_parser_omp_clause_map (cp_parser *par
/*consume_paren=*/true);
return list;
}
+ if (always)
+ kind = (enum gomp_map_kind) (kind | GOMP_MAP_FLAG_FORCE);
cp_lexer_consume_token (parser->lexer);
cp_lexer_consume_token (parser->lexer);
}
@@ -29360,6 +29581,11 @@ cp_parser_omp_all_clauses (cp_parser *pa
clauses);
c_name = "firstprivate";
break;
+ case PRAGMA_OMP_CLAUSE_GRAINSIZE:
+ clauses = cp_parser_omp_clause_grainsize (parser, clauses,
+ token->location);
+ c_name = "grainsize";
+ break;
case PRAGMA_OMP_CLAUSE_IF:
clauses = cp_parser_omp_clause_if (parser, clauses, token->location);
c_name = "if";
@@ -29378,6 +29604,11 @@ cp_parser_omp_all_clauses (cp_parser *pa
clauses = cp_parser_omp_clause_nowait (parser, clauses, token->location);
c_name = "nowait";
break;
+ case PRAGMA_OMP_CLAUSE_NUM_TASKS:
+ clauses = cp_parser_omp_clause_num_tasks (parser, clauses,
+ token->location);
+ c_name = "num_tasks";
+ break;
case PRAGMA_OMP_CLAUSE_NUM_THREADS:
clauses = cp_parser_omp_clause_num_threads (parser, clauses,
token->location);
@@ -29388,6 +29619,11 @@ cp_parser_omp_all_clauses (cp_parser *pa
token->location);
c_name = "ordered";
break;
+ case PRAGMA_OMP_CLAUSE_PRIORITY:
+ clauses = cp_parser_omp_clause_priority (parser, clauses,
+ token->location);
+ c_name = "priority";
+ break;
case PRAGMA_OMP_CLAUSE_PRIVATE:
clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_PRIVATE,
clauses);
@@ -29494,7 +29730,8 @@ cp_parser_omp_all_clauses (cp_parser *pa
c_name = "linear";
break;
case PRAGMA_OMP_CLAUSE_DEPEND:
- clauses = cp_parser_omp_clause_depend (parser, clauses);
+ clauses = cp_parser_omp_clause_depend (parser, clauses,
+ token->location);
c_name = "depend";
break;
case PRAGMA_OMP_CLAUSE_MAP:
@@ -29526,6 +29763,23 @@ cp_parser_omp_all_clauses (cp_parser *pa
token->location);
c_name = "simdlen";
break;
+ case PRAGMA_OMP_CLAUSE_NOGROUP:
+ clauses = cp_parser_omp_clause_nogroup (parser, clauses,
+ token->location);
+ c_name = "nogroup";
+ break;
+ case PRAGMA_OMP_CLAUSE_THREADS:
+ clauses
+ = cp_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
+ clauses, token->location);
+ c_name = "threads";
+ break;
+ case PRAGMA_OMP_CLAUSE_SIMD:
+ clauses
+ = cp_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
+ clauses, token->location);
+ c_name = "simd";
+ break;
case PRAGMA_CILK_CLAUSE_VECTORLENGTH:
clauses = cp_parser_cilk_simd_vectorlength (parser, clauses, true);
c_name = "simdlen";
@@ -30689,6 +30943,7 @@ cp_omp_split_clauses (location_t loc, en
#define OMP_SIMD_CLAUSE_MASK \
( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
@@ -30739,6 +30994,7 @@ cp_parser_omp_simd (cp_parser *parser, c
( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
@@ -30829,15 +31085,62 @@ cp_parser_omp_master (cp_parser *parser,
/* OpenMP 2.5:
# pragma omp ordered new-line
+ structured-block
+
+ OpenMP 4.1:
+ # pragma omp ordered ordered-clauses new-line
structured-block */
-static tree
-cp_parser_omp_ordered (cp_parser *parser, cp_token *pragma_tok)
+#define OMP_ORDERED_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
+
+#define OMP_ORDERED_DEPEND_CLAUSE_MASK \
+ (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
+
+static bool
+cp_parser_omp_ordered (cp_parser *parser, cp_token *pragma_tok,
+ enum pragma_context context)
{
- location_t loc = cp_lexer_peek_token (parser->lexer)->location;
- cp_parser_require_pragma_eol (parser, pragma_tok);
- return c_finish_omp_ordered (loc, NULL_TREE,
- cp_parser_omp_structured_block (parser));
+ location_t loc = pragma_tok->location;
+
+ if (context != pragma_stmt && context != pragma_compound)
+ {
+ cp_parser_error (parser, "expected declaration specifiers");
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return false;
+ }
+
+ 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, "depend") == 0)
+ {
+ if (context == pragma_stmt)
+ {
+ error_at (pragma_tok->location, "%<#pragma omp ordered%> with "
+ "%<depend%> clause may only be used in compound "
+ "statements");
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return false;
+ }
+ tree clauses
+ = cp_parser_omp_all_clauses (parser,
+ OMP_ORDERED_DEPEND_CLAUSE_MASK,
+ "#pragma omp ordered", pragma_tok);
+ c_finish_omp_ordered (loc, clauses, NULL_TREE);
+ return false;
+ }
+ }
+
+ tree clauses
+ = cp_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
+ "#pragma omp ordered", pragma_tok);
+ c_finish_omp_ordered (loc, clauses,
+ cp_parser_omp_structured_block (parser));
+ return true;
}
/* OpenMP 2.5:
@@ -31075,7 +31378,8 @@ cp_parser_omp_single (cp_parser *parser,
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND))
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY))
static tree
cp_parser_omp_task (cp_parser *parser, cp_token *pragma_tok)
@@ -31379,12 +31683,21 @@ cp_parser_omp_teams (cp_parser *parser,
static tree
cp_parser_omp_target_data (cp_parser *parser, cp_token *pragma_tok)
{
+ tree clauses
+ = cp_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
+ "#pragma omp target data", pragma_tok);
+ if (find_omp_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
+ {
+ error_at (pragma_tok->location,
+ "%<#pragma omp target data%> must contain at least one "
+ "%<map%> clause");
+ return NULL_TREE;
+ }
+
tree stmt = make_node (OMP_TARGET_DATA);
TREE_TYPE (stmt) = void_type_node;
+ OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
- OMP_TARGET_DATA_CLAUSES (stmt)
- = cp_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
- "#pragma omp target data", pragma_tok);
keep_next_level (true);
OMP_TARGET_DATA_BODY (stmt) = cp_parser_omp_structured_block (parser);
@@ -31392,6 +31705,172 @@ cp_parser_omp_target_data (cp_parser *pa
return add_stmt (stmt);
}
+/* OpenMP 4.1:
+ # pragma omp target enter data target-enter-data-clause[optseq] new-line
+ structured-block */
+
+#define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
+
+static tree
+cp_parser_omp_target_enter_data (cp_parser *parser, cp_token *pragma_tok,
+ enum pragma_context context)
+{
+ bool data_seen = false;
+ 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, "data") == 0)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ data_seen = true;
+ }
+ }
+ if (!data_seen)
+ {
+ cp_parser_error (parser, "expected %<data%>");
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return NULL_TREE;
+ }
+
+ if (context == pragma_stmt)
+ {
+ error_at (pragma_tok->location,
+ "%<#pragma omp target enter data%> may only be "
+ "used in compound statements");
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return NULL_TREE;
+ }
+
+ tree clauses
+ = cp_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
+ "#pragma omp target enter data", pragma_tok);
+ int map_seen = 0;
+ for (tree *pc = &clauses; *pc;)
+ {
+ if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
+ switch (OMP_CLAUSE_MAP_KIND (*pc) & ~GOMP_MAP_FLAG_FORCE)
+ {
+ case GOMP_MAP_TO:
+ case GOMP_MAP_ALLOC:
+ map_seen = 3;
+ break;
+ default:
+ map_seen |= 1;
+ error_at (OMP_CLAUSE_LOCATION (*pc),
+ "%<#pragma omp target enter data%> with map-type other "
+ "than %<to%> or %<alloc%> on %<map%> clause");
+ *pc = OMP_CLAUSE_CHAIN (*pc);
+ continue;
+ }
+ pc = &OMP_CLAUSE_CHAIN (*pc);
+ }
+
+ if (map_seen != 3)
+ {
+ if (map_seen == 0)
+ error_at (pragma_tok->location,
+ "%<#pragma omp target enter data%> must contain at least "
+ "one %<map%> clause");
+ return NULL_TREE;
+ }
+
+ tree stmt = make_node (OMP_TARGET_ENTER_DATA);
+ TREE_TYPE (stmt) = void_type_node;
+ OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
+ SET_EXPR_LOCATION (stmt, pragma_tok->location);
+ return add_stmt (stmt);
+}
+
+/* OpenMP 4.1:
+ # pragma omp target exit data target-enter-data-clause[optseq] new-line
+ structured-block */
+
+#define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
+
+static tree
+cp_parser_omp_target_exit_data (cp_parser *parser, cp_token *pragma_tok,
+ enum pragma_context context)
+{
+ bool data_seen = false;
+ 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, "data") == 0)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ data_seen = true;
+ }
+ }
+ if (!data_seen)
+ {
+ cp_parser_error (parser, "expected %<data%>");
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return NULL_TREE;
+ }
+
+ if (context == pragma_stmt)
+ {
+ error_at (pragma_tok->location,
+ "%<#pragma omp target exit data%> may only be "
+ "used in compound statements");
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return NULL_TREE;
+ }
+
+ tree clauses
+ = cp_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
+ "#pragma omp target exit data", pragma_tok);
+ int map_seen = 0;
+ for (tree *pc = &clauses; *pc;)
+ {
+ if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
+ switch (OMP_CLAUSE_MAP_KIND (*pc) & ~GOMP_MAP_FLAG_FORCE)
+ {
+ case GOMP_MAP_FROM:
+ case GOMP_MAP_FORCE_DEALLOC & ~GOMP_MAP_FLAG_FORCE:
+ map_seen = 3;
+ break;
+ default:
+ map_seen |= 1;
+ error_at (OMP_CLAUSE_LOCATION (*pc),
+ "%<#pragma omp target exit data%> with map-type other "
+ "than %<from%> or %<delete%> on %<map%> clause");
+ *pc = OMP_CLAUSE_CHAIN (*pc);
+ continue;
+ }
+ pc = &OMP_CLAUSE_CHAIN (*pc);
+ }
+
+ if (map_seen != 3)
+ {
+ if (map_seen == 0)
+ error_at (pragma_tok->location,
+ "%<#pragma omp target exit data%> must contain at least "
+ "one %<map%> clause");
+ return NULL_TREE;
+ }
+
+ tree stmt = make_node (OMP_TARGET_EXIT_DATA);
+ TREE_TYPE (stmt) = void_type_node;
+ OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
+ SET_EXPR_LOCATION (stmt, pragma_tok->location);
+ return add_stmt (stmt);
+}
+
/* OpenMP 4.0:
# pragma omp target update target-update-clause[optseq] new-line */
@@ -31399,7 +31878,9 @@ cp_parser_omp_target_data (cp_parser *pa
( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
static bool
cp_parser_omp_target_update (cp_parser *parser, cp_token *pragma_tok,
@@ -31441,7 +31922,9 @@ cp_parser_omp_target_update (cp_parser *
#define OMP_TARGET_CLAUSE_MASK \
( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
static bool
cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok,
@@ -31501,6 +31984,18 @@ cp_parser_omp_target (cp_parser *parser,
cp_parser_omp_target_data (parser, pragma_tok);
return true;
}
+ else if (strcmp (p, "enter") == 0)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ cp_parser_omp_target_enter_data (parser, pragma_tok, context);
+ return false;
+ }
+ else if (strcmp (p, "exit") == 0)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ cp_parser_omp_target_exit_data (parser, pragma_tok, context);
+ return false;
+ }
else if (strcmp (p, "update") == 0)
{
cp_lexer_consume_token (parser->lexer);
@@ -32480,6 +32975,96 @@ cp_parser_omp_declare (cp_parser *parser
cp_parser_require_pragma_eol (parser, pragma_tok);
}
+/* OpenMP 4.1:
+7 #pragma omp taskloop taskloop-clause[optseq] new-line
+ for-loop
+
+ #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
+ for-loop */
+
+#define OMP_TASKLOOP_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
+
+static tree
+cp_parser_omp_taskloop (cp_parser *parser, cp_token *pragma_tok,
+ char *p_name, omp_clause_mask mask, tree *cclauses)
+{
+ tree clauses, sb, ret;
+ unsigned int save;
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+
+ strcat (p_name, " taskloop");
+ mask |= OMP_TASKLOOP_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, "simd") == 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_simd (parser, pragma_tok, p_name, mask,
+ cclauses);
+ sb = begin_omp_structured_block ();
+ save = cp_parser_begin_omp_structured_block (parser);
+ ret = cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
+ cclauses);
+ cp_parser_end_omp_structured_block (parser, save);
+ tree body = finish_omp_structured_block (sb);
+ if (ret == NULL)
+ return ret;
+ ret = make_node (OMP_TASKLOOP);
+ TREE_TYPE (ret) = void_type_node;
+ OMP_FOR_BODY (ret) = body;
+ OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
+ SET_EXPR_LOCATION (ret, loc);
+ add_stmt (ret);
+ 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_TASKLOOP, mask, clauses, cclauses);
+ clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
+ }
+
+ sb = begin_omp_structured_block ();
+ save = cp_parser_begin_omp_structured_block (parser);
+
+ ret = cp_parser_omp_for_loop (parser, OMP_TASKLOOP, clauses, cclauses);
+
+ cp_parser_end_omp_structured_block (parser, save);
+ add_stmt (finish_omp_structured_block (sb));
+
+ return ret;
+}
+
/* Main entry point to OpenMP statement pragmas. */
static void
@@ -32535,9 +33120,6 @@ cp_parser_omp_construct (cp_parser *pars
case PRAGMA_OMP_MASTER:
stmt = cp_parser_omp_master (parser, pragma_tok);
break;
- case PRAGMA_OMP_ORDERED:
- stmt = cp_parser_omp_ordered (parser, pragma_tok);
- break;
case PRAGMA_OMP_PARALLEL:
strcpy (p_name, "#pragma omp");
stmt = cp_parser_omp_parallel (parser, pragma_tok, p_name, mask, NULL);
@@ -32559,6 +33141,10 @@ cp_parser_omp_construct (cp_parser *pars
case PRAGMA_OMP_TASKGROUP:
stmt = cp_parser_omp_taskgroup (parser, pragma_tok);
break;
+ case PRAGMA_OMP_TASKLOOP:
+ strcpy (p_name, "#pragma omp");
+ stmt = cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask, NULL);
+ break;
case PRAGMA_OMP_TEAMS:
strcpy (p_name, "#pragma omp");
stmt = cp_parser_omp_teams (parser, pragma_tok, p_name, mask, NULL);
@@ -33074,19 +33660,22 @@ cp_parser_pragma (cp_parser *parser, enu
case PRAGMA_OMP_DISTRIBUTE:
case PRAGMA_OMP_FOR:
case PRAGMA_OMP_MASTER:
- case PRAGMA_OMP_ORDERED:
case PRAGMA_OMP_PARALLEL:
case PRAGMA_OMP_SECTIONS:
case PRAGMA_OMP_SIMD:
case PRAGMA_OMP_SINGLE:
case PRAGMA_OMP_TASK:
case PRAGMA_OMP_TASKGROUP:
+ case PRAGMA_OMP_TASKLOOP:
case PRAGMA_OMP_TEAMS:
if (context != pragma_stmt && context != pragma_compound)
goto bad_stmt;
cp_parser_omp_construct (parser, pragma_tok);
return true;
+ case PRAGMA_OMP_ORDERED:
+ return cp_parser_omp_ordered (parser, pragma_tok, context);
+
case PRAGMA_OMP_TARGET:
return cp_parser_omp_target (parser, pragma_tok, context);
@@ -13476,6 +13476,10 @@ tsubst_omp_clauses (tree clauses, bool d
case OMP_CLAUSE_THREAD_LIMIT:
case OMP_CLAUSE_SAFELEN:
case OMP_CLAUSE_SIMDLEN:
+ case OMP_CLAUSE_NUM_TASKS:
+ case OMP_CLAUSE_GRAINSIZE:
+ case OMP_CLAUSE_PRIORITY:
+ case OMP_CLAUSE_ORDERED:
OMP_CLAUSE_OPERAND (nc, 0)
= tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain,
in_decl, /*integral_constant_expression_p=*/false);
@@ -13511,7 +13515,6 @@ tsubst_omp_clauses (tree clauses, bool d
break;
case OMP_CLAUSE_NOWAIT:
- case OMP_CLAUSE_ORDERED:
case OMP_CLAUSE_DEFAULT:
case OMP_CLAUSE_UNTIED:
case OMP_CLAUSE_MERGEABLE:
@@ -13522,6 +13525,9 @@ tsubst_omp_clauses (tree clauses, bool d
case OMP_CLAUSE_PARALLEL:
case OMP_CLAUSE_SECTIONS:
case OMP_CLAUSE_TASKGROUP:
+ case OMP_CLAUSE_NOGROUP:
+ case OMP_CLAUSE_THREADS:
+ case OMP_CLAUSE_SIMD:
break;
default:
gcc_unreachable ();
@@ -14152,6 +14158,7 @@ tsubst_expr (tree t, tree args, tsubst_f
case CILK_SIMD:
case CILK_FOR:
case OMP_DISTRIBUTE:
+ case OMP_TASKLOOP:
{
tree clauses, body, pre_body;
tree declv = NULL_TREE, initv = NULL_TREE, condv = NULL_TREE;
@@ -5301,6 +5301,7 @@ finish_omp_clauses (tree clauses)
bitmap_head generic_head, firstprivate_head, lastprivate_head;
bitmap_head aligned_head;
tree c, t, *pc;
+ tree safelen = NULL_TREE;
bool branch_seen = false;
bool copyprivate_seen = false;
@@ -5484,7 +5485,17 @@ finish_omp_clauses (tree clauses)
{
t = mark_rvalue_use (t);
if (!processing_template_decl)
- t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ {
+ t = maybe_constant_value (t);
+ if (TREE_CODE (t) == INTEGER_CST
+ && tree_int_cst_sgn (t) != 1)
+ {
+ warning_at (OMP_CLAUSE_LOCATION (c), 0,
+ "%<num_threads%> value must be positive");
+ t = integer_one_node;
+ }
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ }
OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
}
break;
@@ -5552,6 +5563,8 @@ finish_omp_clauses (tree clauses)
}
}
OMP_CLAUSE_OPERAND (c, 0) = t;
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SAFELEN)
+ safelen = c;
}
break;
@@ -5569,7 +5582,17 @@ finish_omp_clauses (tree clauses)
{
t = mark_rvalue_use (t);
if (!processing_template_decl)
- t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ {
+ t = maybe_constant_value (t);
+ if (TREE_CODE (t) == INTEGER_CST
+ && tree_int_cst_sgn (t) != 1)
+ {
+ warning_at (OMP_CLAUSE_LOCATION (c), 0,
+ "%<num_teams%> value must be positive");
+ t = integer_one_node;
+ }
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ }
OMP_CLAUSE_NUM_TEAMS_EXPR (c) = t;
}
break;
@@ -5626,7 +5649,17 @@ finish_omp_clauses (tree clauses)
{
t = mark_rvalue_use (t);
if (!processing_template_decl)
- t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ {
+ t = maybe_constant_value (t);
+ if (TREE_CODE (t) == INTEGER_CST
+ && tree_int_cst_sgn (t) != 1)
+ {
+ warning_at (OMP_CLAUSE_LOCATION (c), 0,
+ "%<thread_limit%> value must be positive");
+ t = integer_one_node;
+ }
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ }
OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
}
break;
@@ -5736,6 +5769,12 @@ finish_omp_clauses (tree clauses)
case OMP_CLAUSE_DEPEND:
t = OMP_CLAUSE_DECL (c);
+ if (t == NULL_TREE)
+ {
+ gcc_assert (OMP_CLAUSE_DEPEND_KIND (c)
+ == OMP_CLAUSE_DEPEND_SOURCE);
+ break;
+ }
if (TREE_CODE (t) == TREE_LIST)
{
if (handle_omp_array_sections (c))
@@ -5851,6 +5890,93 @@ finish_omp_clauses (tree clauses)
}
goto check_dup_generic;
+ case OMP_CLAUSE_NUM_TASKS:
+ t = OMP_CLAUSE_NUM_TASKS_EXPR (c);
+ if (t == error_mark_node)
+ remove = true;
+ else if (!type_dependent_expression_p (t)
+ && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
+ {
+ error ("%<num_tasks%> expression must be integral");
+ remove = true;
+ }
+ else
+ {
+ t = mark_rvalue_use (t);
+ if (!processing_template_decl)
+ {
+ t = maybe_constant_value (t);
+ if (TREE_CODE (t) == INTEGER_CST
+ && tree_int_cst_sgn (t) != 1)
+ {
+ warning_at (OMP_CLAUSE_LOCATION (c), 0,
+ "%<num_tasks%> value must be positive");
+ t = integer_one_node;
+ }
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ }
+ OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
+ }
+ break;
+
+ case OMP_CLAUSE_GRAINSIZE:
+ t = OMP_CLAUSE_GRAINSIZE_EXPR (c);
+ if (t == error_mark_node)
+ remove = true;
+ else if (!type_dependent_expression_p (t)
+ && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
+ {
+ error ("%<grainsize%> expression must be integral");
+ remove = true;
+ }
+ else
+ {
+ t = mark_rvalue_use (t);
+ if (!processing_template_decl)
+ {
+ t = maybe_constant_value (t);
+ if (TREE_CODE (t) == INTEGER_CST
+ && tree_int_cst_sgn (t) != 1)
+ {
+ warning_at (OMP_CLAUSE_LOCATION (c), 0,
+ "%<grainsize%> value must be positive");
+ t = integer_one_node;
+ }
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ }
+ OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
+ }
+ break;
+
+ case OMP_CLAUSE_PRIORITY:
+ t = OMP_CLAUSE_PRIORITY_EXPR (c);
+ if (t == error_mark_node)
+ remove = true;
+ else if (!type_dependent_expression_p (t)
+ && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
+ {
+ error ("%<priority%> expression must be integral");
+ remove = true;
+ }
+ else
+ {
+ t = mark_rvalue_use (t);
+ if (!processing_template_decl)
+ {
+ t = maybe_constant_value (t);
+ if (TREE_CODE (t) == INTEGER_CST
+ && tree_int_cst_sgn (t) == -1)
+ {
+ warning_at (OMP_CLAUSE_LOCATION (c), 0,
+ "%<priority%> value must be non-negative");
+ t = integer_one_node;
+ }
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ }
+ OMP_CLAUSE_PRIORITY_EXPR (c) = t;
+ }
+ break;
+
case OMP_CLAUSE_NOWAIT:
case OMP_CLAUSE_ORDERED:
case OMP_CLAUSE_DEFAULT:
@@ -5862,6 +5988,9 @@ finish_omp_clauses (tree clauses)
case OMP_CLAUSE_SECTIONS:
case OMP_CLAUSE_TASKGROUP:
case OMP_CLAUSE_PROC_BIND:
+ case OMP_CLAUSE_NOGROUP:
+ case OMP_CLAUSE_THREADS:
+ case OMP_CLAUSE_SIMD:
case OMP_CLAUSE__CILK_FOR_COUNT_:
break;
@@ -5929,6 +6058,20 @@ finish_omp_clauses (tree clauses)
case OMP_CLAUSE_COPYIN:
need_copy_assignment = true;
break;
+ case OMP_CLAUSE_SIMDLEN:
+ if (safelen
+ && !processing_template_decl
+ && tree_int_cst_lt (OMP_CLAUSE_SAFELEN_EXPR (safelen),
+ OMP_CLAUSE_SIMDLEN_EXPR (c)))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%<simdlen%> clause value is bigger than "
+ "%<safelen%> clause value");
+ OMP_CLAUSE_SIMDLEN_EXPR (c)
+ = OMP_CLAUSE_SAFELEN_EXPR (safelen);
+ }
+ pc = &OMP_CLAUSE_CHAIN (c);
+ continue;
case OMP_CLAUSE_NOWAIT:
if (copyprivate_seen)
{
@@ -703,6 +703,7 @@ cp_gimplify_expr (tree *expr_p, gimple_s
case OMP_FOR:
case OMP_SIMD:
case OMP_DISTRIBUTE:
+ case OMP_TASKLOOP:
ret = cp_gimplify_omp_for (expr_p, pre_p);
break;
@@ -1258,7 +1259,8 @@ cp_genericize_r (tree *stmt_p, int *walk
genericize_break_stmt (stmt_p);
else if (TREE_CODE (stmt) == OMP_FOR
|| TREE_CODE (stmt) == OMP_SIMD
- || TREE_CODE (stmt) == OMP_DISTRIBUTE)
+ || TREE_CODE (stmt) == OMP_DISTRIBUTE
+ || TREE_CODE (stmt) == OMP_TASKLOOP)
genericize_omp_for_stmt (stmt_p, walk_subtrees, data);
else if (TREE_CODE (stmt) == SIZEOF_EXPR)
{
@@ -65,7 +65,8 @@ c-common.h, not after.
STMT_EXPR_NO_SCOPE (in STMT_EXPR)
BIND_EXPR_TRY_BLOCK (in BIND_EXPR)
TYPENAME_IS_ENUM_P (in TYPENAME_TYPE)
- OMP_FOR_GIMPLIFYING_P (in OMP_FOR, OMP_SIMD and OMP_DISTRIBUTE)
+ OMP_FOR_GIMPLIFYING_P (in OMP_FOR, OMP_SIMD, OMP_DISTRIBUTE,
+ and OMP_TASKLOOP)
BASELINK_QUALIFIED_P (in BASELINK)
TARGET_EXPR_IMPLICIT_P (in TARGET_EXPR)
TEMPLATE_PARM_PARAMETER_PACK (in TEMPLATE_PARM_INDEX)
@@ -1,15 +0,0 @@
-/* { dg-do compile } */
-
-int e;
-int bar (int, int);
-void baz (int, int, int, int *, int *, int *);
-
-void
-foo (int a, int b, int c, int d, int f, int g, int h, int j, int k, int l)
-{
- int i;
- #pragma omp taskloop if (a) final (b) untied default(none) mergeable \
- private(c) firstprivate (e) shared (d) num_tasks(f) collapse(1)
- for (i = bar (g, h) + j; i < k; i += l)
- baz (i, d, e++, &c, &d, &e);
-}
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+int e;
+int bar (int, int);
+void baz (int, int, int, int *, int *, int *);
+
+void
+foo (int a, int b, int c, int d, int f, int g, int h, int j, int k, int l)
+{
+ int i;
+ #pragma omp taskloop if (a) final (b) untied default(none) mergeable \
+ private(c) firstprivate (e) shared (d) num_tasks(f) collapse(1)
+ for (i = bar (g, h) + j; i < k; i += l)
+ baz (i, d, e++, &c, &d, &e);
+}
@@ -0,0 +1,42 @@
+/* { dg-options "-fopenmp" } */
+
+extern "C" void abort (void);
+
+#define M(x, y, z) O(x, y, z)
+#define O(x, y, z) x ## _ ## y ## _ ## z
+
+#define F taskloop
+#define G taskloop
+#define S
+#define N(x) M(x, G, normal)
+#include "../libgomp.c/for-2.h"
+#undef S
+#undef N
+#undef F
+#undef G
+
+#define F taskloop simd
+#define G taskloop_simd
+#define S
+#define N(x) M(x, G, normal)
+#include "../libgomp.c/for-2.h"
+#undef S
+#undef N
+#undef F
+#undef G
+
+int
+main ()
+{
+ int err = 0;
+ #pragma omp parallel reduction(|:err)
+ #pragma omp single
+ {
+ if (test_taskloop_normal ()
+ || test_taskloop_simd_normal ())
+ err = 1;
+ }
+ if (err)
+ abort ();
+ return 0;
+}
@@ -0,0 +1,4 @@
+// { dg-do run }
+// { dg-options "-O2 -fopenmp" }
+
+#include "../libgomp.c/taskloop-1.c"
@@ -0,0 +1,6 @@
+// { dg-do run }
+// { dg-options "-O2" }
+// { dg-additional-options "-msse2" { target sse2_runtime } }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+
+#include "../libgomp.c/taskloop-2.c"
@@ -0,0 +1,4 @@
+// { dg-do run }
+// { dg-options "-O2 -fopenmp" }
+
+#include "../libgomp.c/taskloop-3.c"
@@ -0,0 +1,4 @@
+// { dg-do run }
+// { dg-options "-O2 -fopenmp" }
+
+#include "../libgomp.c/taskloop-4.c"