@@ -6420,6 +6420,7 @@ gimplify_scan_omp_clauses (tree *list_p,
case OMP_CLAUSE_SCHEDULE:
case OMP_CLAUSE_NUM_THREADS:
case OMP_CLAUSE_NUM_TEAMS:
+ case OMP_CLAUSE_THREAD_LIMIT:
case OMP_CLAUSE_DIST_SCHEDULE:
case OMP_CLAUSE_DEVICE:
if (gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
@@ -257,6 +257,7 @@ unsigned const char omp_clause_num_ops[]
0, /* OMP_CLAUSE_INBRANCH */
0, /* OMP_CLAUSE_NOTINBRANCH */
1, /* OMP_CLAUSE_NUM_TEAMS */
+ 1, /* OMP_CLAUSE_THREAD_LIMIT */
0, /* OMP_CLAUSE_PROC_BIND */
1, /* OMP_CLAUSE_SAFELEN */
1, /* OMP_CLAUSE_SIMDLEN */
@@ -298,6 +299,7 @@ const char * const omp_clause_code_name[
"inbranch",
"notinbranch",
"num_teams",
+ "thread_limit",
"proc_bind",
"safelen",
"simdlen",
@@ -11014,6 +11016,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func
case OMP_CLAUSE_UNIFORM:
case OMP_CLAUSE_DEPEND:
case OMP_CLAUSE_NUM_TEAMS:
+ case OMP_CLAUSE_THREAD_LIMIT:
case OMP_CLAUSE_DEVICE:
case OMP_CLAUSE_DIST_SCHEDULE:
case OMP_CLAUSE_SAFELEN:
@@ -4779,6 +4779,25 @@ finish_omp_clauses (tree clauses)
}
break;
+ case OMP_CLAUSE_THREAD_LIMIT:
+ t = OMP_CLAUSE_THREAD_LIMIT_EXPR (c);
+ if (t == error_mark_node)
+ remove = true;
+ else if (!type_dependent_expression_p (t)
+ && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
+ {
+ error ("%<thread_limit%> expression must be integral");
+ remove = true;
+ }
+ else
+ {
+ t = mark_rvalue_use (t);
+ if (!processing_template_decl)
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
+ }
+ break;
+
case OMP_CLAUSE_DEVICE:
t = OMP_CLAUSE_DEVICE_ID (c);
if (t == error_mark_node)
@@ -26225,6 +26225,8 @@ cp_parser_omp_clause_name (cp_parser *pa
case 't':
if (!strcmp ("taskgroup", p))
result = PRAGMA_OMP_CLAUSE_TASKGROUP;
+ else if (!strcmp ("thread_limit", p))
+ result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
else if (!strcmp ("to", p))
result = PRAGMA_OMP_CLAUSE_TO;
break;
@@ -26892,6 +26900,36 @@ cp_parser_omp_clause_num_teams (cp_parse
}
/* OpenMP 4.0:
+ thread_limit ( expression ) */
+
+static tree
+cp_parser_omp_clause_thread_limit (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, false, NULL);
+
+ 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_THREAD_LIMIT,
+ "thread_limit", location);
+
+ c = build_omp_clause (location, OMP_CLAUSE_THREAD_LIMIT);
+ OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
+ OMP_CLAUSE_CHAIN (c) = list;
+
+ return c;
+}
+
+/* OpenMP 4.0:
aligned ( variable-list )
aligned ( variable-list : constant-expression ) */
@@ -27429,6 +27463,11 @@ cp_parser_omp_all_clauses (cp_parser *pa
token->location);
c_name = "num_teams";
break;
+ case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
+ clauses = cp_parser_omp_clause_thread_limit (parser, clauses,
+ token->location);
+ c_name = "thread_limit";
+ break;
case PRAGMA_OMP_CLAUSE_ALIGNED:
clauses = cp_parser_omp_clause_aligned (parser, clauses);
c_name = "aligned";
@@ -29058,7 +29097,7 @@ cp_parser_omp_cancellation_point (cp_par
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
static tree
@@ -12667,6 +12667,7 @@ tsubst_omp_clauses (tree clauses, bool d
case OMP_CLAUSE_DEVICE:
case OMP_CLAUSE_DIST_SCHEDULE:
case OMP_CLAUSE_NUM_TEAMS:
+ case OMP_CLAUSE_THREAD_LIMIT:
case OMP_CLAUSE_SAFELEN:
case OMP_CLAUSE_SIMDLEN:
OMP_CLAUSE_OPERAND (nc, 0)
@@ -533,6 +533,13 @@ dump_omp_clause (pretty_printer *buffer,
pp_character (buffer, ')');
break;
+ case OMP_CLAUSE_THREAD_LIMIT:
+ pp_string (buffer, "thread_limit(");
+ dump_generic_node (buffer, OMP_CLAUSE_THREAD_LIMIT_EXPR (clause),
+ spc, flags, false);
+ pp_character (buffer, ')');
+ break;
+
case OMP_CLAUSE_DEVICE:
pp_string (buffer, "device(");
dump_generic_node (buffer, OMP_CLAUSE_DEVICE_ID (clause),
@@ -431,6 +431,9 @@ enum omp_clause_code
/* OpenMP clause: num_teams(integer-expression). */
OMP_CLAUSE_NUM_TEAMS,
+ /* OpenMP clause: thread_limit(integer-expression). */
+ OMP_CLAUSE_THREAD_LIMIT,
+
/* OpenMP clause: proc_bind ({master,close,spread}). */
OMP_CLAUSE_PROC_BIND,
@@ -1978,6 +1981,10 @@ extern void protected_set_expr_location
#define OMP_CLAUSE_NUM_TEAMS_EXPR(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_NUM_TEAMS), 0)
+#define OMP_CLAUSE_THREAD_LIMIT_EXPR(NODE) \
+ OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, \
+ OMP_CLAUSE_THREAD_LIMIT), 0)
+
#define OMP_CLAUSE_DEVICE_ID(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DEVICE), 0)
@@ -104,6 +104,7 @@ typedef enum pragma_omp_clause {
PRAGMA_OMP_CLAUSE_SHARED,
PRAGMA_OMP_CLAUSE_SIMDLEN,
PRAGMA_OMP_CLAUSE_TASKGROUP,
+ PRAGMA_OMP_CLAUSE_THREAD_LIMIT,
PRAGMA_OMP_CLAUSE_TO,
PRAGMA_OMP_CLAUSE_UNIFORM,
PRAGMA_OMP_CLAUSE_UNTIED