C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
C_IS_RESERVED_WORD (id) = 1;
}
+
+ if (flag_openmp)
+ {
+ id = get_identifier ("omp_all_memory");
+ C_SET_RID_CODE (id, RID_OMP_ALL_MEMORY);
+ C_IS_RESERVED_WORD (id) = 1;
+ ridpointers [RID_OMP_ALL_MEMORY] = id;
+ }
}
\f
/* A parser structure recording information about the state and
parser->error = false;
}
-/* CPP's options (initialized by c-opts.c). */
+/* CPP's options (initialized by c-opts.cc). */
extern cpp_options *cpp_opts;
/* Save the warning flags which are controlled by __extension__. */
c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
- if (__builtin_expect (omp_atomic_lhs != NULL, 0)
+ if (UNLIKELY (omp_atomic_lhs != NULL)
&& (TREE_CODE (cond.value) == GT_EXPR
|| TREE_CODE (cond.value) == LT_EXPR
|| TREE_CODE (cond.value) == EQ_EXPR)
stack[sp].expr \
= convert_lvalue_to_rvalue (stack[sp].loc, \
stack[sp].expr, true, true); \
- if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1 \
+ if (UNLIKELY (omp_atomic_lhs != NULL_TREE) && sp == 1 \
&& ((c_parser_next_token_is (parser, CPP_SEMICOLON) \
&& ((1 << stack[sp].prec) \
& ((1 << PREC_BITOR) | (1 << PREC_BITXOR) \
if (c_parser_next_token_is (parser, CPP_NAME))
{
c_token *comp_tok = c_parser_peek_token (parser);
- offsetof_ref = build_component_ref
- (loc, offsetof_ref, comp_tok->value, comp_tok->location);
+ offsetof_ref
+ = build_component_ref (loc, offsetof_ref, comp_tok->value,
+ comp_tok->location, UNKNOWN_LOCATION);
c_parser_consume_token (parser);
while (c_parser_next_token_is (parser, CPP_DOT)
|| c_parser_next_token_is (parser,
break;
}
c_token *comp_tok = c_parser_peek_token (parser);
- offsetof_ref = build_component_ref
- (loc, offsetof_ref, comp_tok->value,
- comp_tok->location);
+ offsetof_ref
+ = build_component_ref (loc, offsetof_ref,
+ comp_tok->value,
+ comp_tok->location,
+ UNKNOWN_LOCATION);
c_parser_consume_token (parser);
}
else
mark_exp_read (e1.value);
location_t end_loc = c_parser_peek_token (parser)->get_finish ();
parens.skip_until_found_close (parser);
- expr.value = build1_loc (loc, PAREN_EXPR, TREE_TYPE (e1.value),
- e1.value);
+ expr = parser_build_unary_op (loc, PAREN_EXPR, e1);
set_c_expr_source_range (&expr, start_loc, end_loc);
}
break;
case RID_GENERIC:
expr = c_parser_generic_selection (parser);
break;
+ case RID_OMP_ALL_MEMORY:
+ gcc_assert (flag_openmp);
+ c_parser_consume_token (parser);
+ error_at (loc, "%<omp_all_memory%> may only be used in OpenMP "
+ "%<depend%> clause");
+ expr.set_error ();
+ break;
default:
c_parser_error (parser, "expected expression");
expr.set_error ();
finish = c_parser_peek_token (parser)->get_finish ();
c_parser_consume_token (parser);
expr.value = build_component_ref (op_loc, expr.value, ident,
- comp_loc);
+ comp_loc, UNKNOWN_LOCATION);
set_c_expr_source_range (&expr, start, finish);
expr.original_code = ERROR_MARK;
if (TREE_CODE (expr.value) != COMPONENT_REF)
build_indirect_ref (op_loc,
expr.value,
RO_ARROW),
- ident, comp_loc);
+ ident, comp_loc,
+ expr.get_location ());
set_c_expr_source_range (&expr, start, finish);
expr.original_code = ERROR_MARK;
if (TREE_CODE (expr.value) != COMPONENT_REF)
else if (!strcmp ("dist_schedule", p))
result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
break;
+ case 'e':
+ if (!strcmp ("enter", p))
+ result = PRAGMA_OMP_CLAUSE_ENTER;
+ break;
case 'f':
if (!strcmp ("filter", p))
result = PRAGMA_OMP_CLAUSE_FILTER;
result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
break;
case 'h':
- if (!strcmp ("hint", p))
+ if (!strcmp ("has_device_addr", p))
+ result = PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR;
+ else if (!strcmp ("hint", p))
result = PRAGMA_OMP_CLAUSE_HINT;
else if (!strcmp ("host", p))
result = PRAGMA_OACC_CLAUSE_HOST;
if (c_parser_next_token_is_not (parser, CPP_NAME)
|| c_parser_peek_token (parser)->id_kind != C_ID_ID)
{
- struct c_expr expr = c_parser_expr_no_commas (parser, NULL);
+ struct c_expr expr;
+ if (kind == OMP_CLAUSE_DEPEND
+ && c_parser_next_token_is_keyword (parser,
+ RID_OMP_ALL_MEMORY)
+ && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
+ || (c_parser_peek_2nd_token (parser)->type
+ == CPP_CLOSE_PAREN)))
+ {
+ expr.value = ridpointers[RID_OMP_ALL_MEMORY];
+ c_parser_consume_token (parser);
+ }
+ else
+ expr = c_parser_expr_no_commas (parser, NULL);
if (expr.value != error_mark_node)
{
tree u = build_omp_clause (clause_loc, kind);
&& c_parser_next_token_is (parser, CPP_DEREF)))
{
location_t op_loc = c_parser_peek_token (parser)->location;
+ location_t arrow_loc = UNKNOWN_LOCATION;
if (c_parser_next_token_is (parser, CPP_DEREF))
- t = build_simple_mem_ref (t);
+ {
+ c_expr t_expr;
+ t_expr.value = t;
+ t_expr.original_code = ERROR_MARK;
+ t_expr.original_type = NULL;
+ set_c_expr_source_range (&t_expr, op_loc, op_loc);
+ t_expr = convert_lvalue_to_rvalue (op_loc, t_expr,
+ true, false);
+ t = build_indirect_ref (op_loc, t_expr.value, RO_ARROW);
+ arrow_loc = t_expr.get_location ();
+ }
c_parser_consume_token (parser);
if (!c_parser_next_token_is (parser, CPP_NAME))
{
tree ident = comp_tok->value;
location_t comp_loc = comp_tok->location;
c_parser_consume_token (parser);
- t = build_component_ref (op_loc, t, ident, comp_loc);
+ t = build_component_ref (op_loc, t, ident, comp_loc,
+ arrow_loc);
}
/* FALLTHROUGH */
case OMP_CLAUSE_AFFINITY:
case OMP_CLAUSE_REDUCTION:
case OMP_CLAUSE_IN_REDUCTION:
case OMP_CLAUSE_TASK_REDUCTION:
+ case OMP_CLAUSE_HAS_DEVICE_ADDR:
array_section_p = false;
dims.truncate (0);
while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
list);
}
+/* OpenMP 5.1:
+ has_device_addr ( variable-list ) */
+
+static tree
+c_parser_omp_clause_has_device_addr (c_parser *parser, tree list)
+{
+ return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_HAS_DEVICE_ADDR,
+ list);
+}
+
/* OpenMP 4.5:
is_device_ptr ( variable-list ) */
OpenMP 4.5:
linear ( modifier ( variable-list ) )
- linear ( modifier ( variable-list ) : expression ) */
+ linear ( modifier ( variable-list ) : expression )
+
+ modifier:
+ val
+
+ OpenMP 5.2:
+ linear ( variable-list : modifiers-list )
+
+ modifiers:
+ val
+ step ( expression ) */
static tree
c_parser_omp_clause_linear (c_parser *parser, tree list)
location_t clause_loc = c_parser_peek_token (parser)->location;
tree nl, c, step;
enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
+ bool old_linear_modifier = false;
matching_parens parens;
if (!parens.require_open (parser))
kind = OMP_CLAUSE_LINEAR_DEFAULT;
if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
{
+ old_linear_modifier = true;
c_parser_consume_token (parser);
c_parser_consume_token (parser);
}
{
c_parser_consume_token (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);
- step = expr.value;
- step = c_fully_fold (step, false, NULL);
- if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
+ bool has_modifiers = false;
+ if (kind == OMP_CLAUSE_LINEAR_DEFAULT
+ && c_parser_next_token_is (parser, CPP_NAME))
+ {
+ c_token *tok = c_parser_peek_token (parser);
+ const char *p = IDENTIFIER_POINTER (tok->value);
+ unsigned int pos = 0;
+ if (strcmp ("val", p) == 0)
+ pos = 2;
+ else if (strcmp ("step", p) == 0
+ && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
+ {
+ pos = 3;
+ if (c_parser_check_balanced_raw_token_sequence (parser, &pos)
+ && (c_parser_peek_nth_token_raw (parser, pos)->type
+ == CPP_CLOSE_PAREN))
+ ++pos;
+ else
+ pos = 0;
+ }
+ if (pos)
+ {
+ tok = c_parser_peek_nth_token_raw (parser, pos);
+ if (tok->type == CPP_COMMA || tok->type == CPP_CLOSE_PAREN)
+ has_modifiers = true;
+ }
+ }
+ if (has_modifiers)
+ {
+ step = NULL_TREE;
+ while (c_parser_next_token_is (parser, CPP_NAME))
+ {
+ c_token *tok = c_parser_peek_token (parser);
+ const char *p = IDENTIFIER_POINTER (tok->value);
+ if (strcmp ("val", p) == 0)
+ {
+ if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
+ error_at (tok->location, "multiple linear modifiers");
+ kind = OMP_CLAUSE_LINEAR_DEFAULT;
+ c_parser_consume_token (parser);
+ }
+ else if (strcmp ("step", p) == 0)
+ {
+ c_parser_consume_token (parser);
+ matching_parens parens2;
+ if (parens2.require_open (parser))
+ {
+ if (step)
+ error_at (tok->location,
+ "multiple %<step%> modifiers");
+ 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);
+ step = c_fully_fold (expr.value, false, NULL);
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
+ {
+ error_at (clause_loc, "%<linear%> clause step "
+ "expression must be integral");
+ step = integer_one_node;
+ }
+ parens2.skip_until_found_close (parser);
+ }
+ else
+ break;
+ }
+ else
+ break;
+ if (c_parser_next_token_is (parser, CPP_COMMA))
+ {
+ c_parser_consume_token (parser);
+ continue;
+ }
+ break;
+ }
+ if (!step)
+ step = integer_one_node;
+ }
+ else
{
- error_at (clause_loc, "%<linear%> clause step expression must "
- "be integral");
- step = integer_one_node;
+ c_expr expr = c_parser_expr_no_commas (parser, NULL);
+ expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
+ step = c_fully_fold (expr.value, false, NULL);
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
+ {
+ error_at (clause_loc, "%<linear%> clause step expression must "
+ "be integral");
+ step = integer_one_node;
+ }
}
}
{
OMP_CLAUSE_LINEAR_STEP (c) = step;
OMP_CLAUSE_LINEAR_KIND (c) = kind;
+ OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c) = old_linear_modifier;
}
parens.skip_until_found_close (parser);
depend ( depend-modifier , depend-kind: variable-list )
depend-kind:
- in | out | inout | mutexinoutset | depobj
+ in | out | inout | mutexinoutset | depobj | inoutset
depend-modifier:
iterator ( iterators-definition ) */
kind = OMP_CLAUSE_DEPEND_IN;
else if (strcmp ("inout", p) == 0)
kind = OMP_CLAUSE_DEPEND_INOUT;
+ else if (strcmp ("inoutset", p) == 0)
+ kind = OMP_CLAUSE_DEPEND_INOUTSET;
else if (strcmp ("mutexinoutset", p) == 0)
kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
else if (strcmp ("out", p) == 0)
else
{
c_parser_error (parser, "%<#pragma omp target%> with "
- "modifier other than %<always%> or %<close%>"
- "on %<map%> clause");
+ "modifier other than %<always%> or "
+ "%<close%> on %<map%> clause");
parens.skip_until_found_close (parser);
return list;
}
break;
case PRAGMA_OMP_CLAUSE_TO:
if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
- clauses
- = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
- clauses);
+ {
+ tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
+ clauses);
+ for (tree c = nl; c != clauses; c = OMP_CLAUSE_CHAIN (c))
+ OMP_CLAUSE_ENTER_TO (c) = 1;
+ clauses = nl;
+ }
else
clauses = c_parser_omp_clause_to (parser, clauses);
c_name = "to";
clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
c_name = "use_device_addr";
break;
+ case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR:
+ clauses = c_parser_omp_clause_has_device_addr (parser, clauses);
+ c_name = "has_device_addr";
+ break;
case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
c_name = "is_device_ptr";
clauses);
c_name = "simd";
break;
+ case PRAGMA_OMP_CLAUSE_ENTER:
+ clauses
+ = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
+ clauses);
+ c_name = "enter";
+ break;
default:
c_parser_error (parser, "expected %<#pragma omp%> clause");
goto saw_error;
kind = OMP_CLAUSE_DEPEND_INOUT;
else if (!strcmp ("mutexinoutset", p2))
kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
+ else if (!strcmp ("inoutset", p2))
+ kind = OMP_CLAUSE_DEPEND_INOUTSET;
}
if (kind == OMP_CLAUSE_DEPEND_SOURCE)
{
clause = error_mark_node;
- error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%> or "
- "%<mutexinoutset%>");
+ error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%>, "
+ "%<mutexinoutset%> or %<inoutset%>");
}
c_parens.skip_until_found_close (parser);
}
#define OMP_SCOPE_CLAUSE_MASK \
( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
static tree
*/
#define OMP_TASKWAIT_CLAUSE_MASK \
- (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
static void
c_parser_omp_taskwait (c_parser *parser)
static tree
c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
{
+ if (flag_openmp)
+ omp_requires_mask
+ = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
+
tree clauses
= c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
"#pragma omp target data");
return false;
}
+ if (flag_openmp)
+ omp_requires_mask
+ = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
+
tree stmt = make_node (OMP_TARGET_UPDATE);
TREE_TYPE (stmt) = void_type_node;
OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
return true;
}
+ if (flag_openmp)
+ omp_requires_mask
+ = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
+
tree clauses
= c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
"#pragma omp target enter data");
case GOMP_MAP_ALLOC:
map_seen = 3;
break;
+ case GOMP_MAP_TOFROM:
+ OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_TO);
+ map_seen = 3;
+ break;
+ case GOMP_MAP_ALWAYS_TOFROM:
+ OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_TO);
+ map_seen = 3;
+ break;
case GOMP_MAP_FIRSTPRIVATE_POINTER:
case GOMP_MAP_ALWAYS_POINTER:
case GOMP_MAP_ATTACH_DETACH:
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");
+ "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
*pc = OMP_CLAUSE_CHAIN (*pc);
continue;
}
return true;
}
+ if (flag_openmp)
+ omp_requires_mask
+ = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
+
tree clauses
= c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
"#pragma omp target exit data");
case GOMP_MAP_DELETE:
map_seen = 3;
break;
+ case GOMP_MAP_TOFROM:
+ OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_FROM);
+ map_seen = 3;
+ break;
+ case GOMP_MAP_ALWAYS_TOFROM:
+ OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_FROM);
+ map_seen = 3;
+ break;
case GOMP_MAP_FIRSTPRIVATE_POINTER:
case GOMP_MAP_ALWAYS_POINTER:
case GOMP_MAP_ATTACH_DETACH:
map_seen |= 1;
error_at (OMP_CLAUSE_LOCATION (*pc),
"%<#pragma omp target exit data%> with map-type other "
- "than %<from%>, %<release%> or %<delete%> on %<map%>"
- " clause");
+ "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
+ "on %<map%> clause");
*pc = OMP_CLAUSE_CHAIN (*pc);
continue;
}
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR))
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
static bool
c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
#define OMP_DECLARE_TARGET_CLAUSE_MASK \
( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
"#pragma omp declare target");
else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
{
- clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
+ clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
clauses);
clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
c_parser_skip_to_pragma_eol (parser);
id = get_identifier ("omp declare target");
if (at2)
{
- error_at (OMP_CLAUSE_LOCATION (c),
- "%qD specified both in declare target %<link%> and %<to%>"
- " clauses", t);
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qD specified both in declare target %<link%> and %qs"
+ " clauses", t, OMP_CLAUSE_ENTER_TO (c) ? "to" : "enter");
+ else
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qD specified both in declare target %<link%> and "
+ "%<to%> or %<enter%> clauses", t);
continue;
}
if (!at1)
c_parser_skip_to_pragma_eol (parser, false);
return;
}
- if (p && this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS)
- sorry_at (cloc, "%qs clause on %<requires%> directive not "
- "supported yet", p);
if (p)
c_parser_consume_token (parser);
if (this_req)