Follow-up to the Fortran patch
r16-5633-g26d41e245dbba3, which (besides
other changes) added parser support for the 'dyn_groupprivate' clause to
the target directive.
This commit adds now the parser support to C/C++ and moves the
not-yet-implemented 'sorry' to the early middle end.
gcc/c-family/ChangeLog:
* c-omp.cc (c_omp_split_clauses): Handle
OMP_CLAUSE_DYN_GROUPPRIVATE, sort target clauses
alphabetically.
* c-pragma.h (enum pragma_omp_clause): Add
PRAGMA_OMP_CLAUSE_DYN_GROUPPRIVATE.
gcc/c/ChangeLog:
* c-parser.cc (c_parser_omp_clause_dyn_groupprivate): New.
(OMP_TARGET_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_DYN_GROUPPRIVATE;
sort clauses alphabetically.
(c_parser_omp_clause_name, c_parser_omp_all_clauses):
Handle 'dyn_groupprivate' clause.
* c-typeck.cc (c_finish_omp_clauses): Likewise.
gcc/cp/ChangeLog:
* pt.cc (tsubst_omp_clauses): Handle OMP_CLAUSE_DYN_GROUPPRIVATE.
* semantics.cc (finish_omp_clauses): Likewise.
* parser.cc (cp_parser_omp_clause_dyn_groupprivate): New.
(cp_parser_omp_clause_name, cp_parser_omp_all_clauses):
Handle 'dyn_groupprivate' clause.
(OMP_TARGET_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_DYN_GROUPPRIVATE;
sort clauses alphabetically.
gcc/fortran/ChangeLog:
* openmp.cc (resolve_omp_clauses): Permit zero with
DYN_GROUPPRIVATE clause.
* trans-openmp.cc (fallback): Generate TREE code
for DYN_GROUPPRIVATE and remove 'sorry'.
gcc/ChangeLog:
* gimplify.cc (gimplify_scan_omp_clauses): Handle
OMP_CLAUSE_DYN_GROUPPRIVATE by printing 'sorry, unimplemented'.
* tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_DYN_GROUPPRIVATE.
(enum omp_clause_fallback_kind): New.
(struct tree_omp_clause): Add fallback_kind union member.
* tree-nested.cc (convert_nonlocal_omp_clauses,
convert_local_omp_clauses): Handle OMP_CLAUSE_DYN_GROUPPRIVATE.
* tree.cc (omp_clause_num_ops, omp_clause_code_name): Add
OMP_CLAUSE_DYN_GROUPPRIVATE.
* tree-pretty-print.cc (dump_omp_clause): Handle
OMP_CLAUSE_DYN_GROUPPRIVATE.
* tree.h (OMP_CLAUSE_DYN_GROUPPRIVATE_EXPR,
OMP_CLAUSE_DYN_GROUPPRIVATE_KIND): New #define.
gcc/testsuite/ChangeLog:
* gfortran.dg/gomp/dyn_groupprivate-1.f90: Add scan-dump test.
* gfortran.dg/gomp/dyn_groupprivate-2.f90: Extend and update.
* c-c++-common/gomp/dyn_groupprivate-1.c: New test.
* c-c++-common/gomp/dyn_groupprivate-2.c: New test.
{
/* First the clauses that are unique to some constructs. */
case OMP_CLAUSE_DEVICE:
- case OMP_CLAUSE_MAP:
- case OMP_CLAUSE_IS_DEVICE_PTR:
- case OMP_CLAUSE_HAS_DEVICE_ADDR:
case OMP_CLAUSE_DEFAULTMAP:
case OMP_CLAUSE_DEPEND:
+ case OMP_CLAUSE_DYN_GROUPPRIVATE:
+ case OMP_CLAUSE_IS_DEVICE_PTR:
+ case OMP_CLAUSE_HAS_DEVICE_ADDR:
+ case OMP_CLAUSE_MAP:
s = C_OMP_CLAUSE_SPLIT_TARGET;
break;
case OMP_CLAUSE_DOACROSS:
PRAGMA_OMP_CLAUSE_DEVICE_TYPE,
PRAGMA_OMP_CLAUSE_DIST_SCHEDULE,
PRAGMA_OMP_CLAUSE_DOACROSS,
+ PRAGMA_OMP_CLAUSE_DYN_GROUPPRIVATE,
PRAGMA_OMP_CLAUSE_ENTER,
PRAGMA_OMP_CLAUSE_FILTER,
PRAGMA_OMP_CLAUSE_FINAL,
result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
else if (!strcmp ("doacross", p))
result = PRAGMA_OMP_CLAUSE_DOACROSS;
+ else if (!strcmp ("dyn_groupprivate", p))
+ result = PRAGMA_OMP_CLAUSE_DYN_GROUPPRIVATE;
break;
case 'e':
if (!strcmp ("enter", p))
return list;
}
+/* OpenMP 6.1:
+ dyn_groupprivate ( [fallback-modifier : ] integer-expression )
+
+ fallback-modifier
+ fallback( abort | default_mem | null ) */
+
+static tree
+c_parser_omp_clause_dyn_groupprivate (c_parser *parser, tree list)
+{
+ location_t clause_loc = c_parser_peek_token (parser)->location;
+ matching_parens parens;
+ if (!parens.require_open (parser))
+ return list;
+
+ enum omp_clause_fallback_kind kind = OMP_CLAUSE_FALLBACK_UNSPECIFIED;
+
+ unsigned n = 3;
+ if (c_parser_next_token_is (parser, CPP_NAME)
+ && (c_parser_peek_2nd_token (parser)->type == CPP_COLON
+ || (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN
+ && c_parser_check_balanced_raw_token_sequence (parser, &n)
+ && (c_parser_peek_nth_token_raw (parser, n)->type
+ == CPP_CLOSE_PAREN)
+ && (c_parser_peek_nth_token_raw (parser, n + 1)->type
+ == CPP_COLON))))
+ {
+ const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+ if (strcmp (p, "fallback") != 0)
+ {
+ c_parser_error (parser, "expected %<fallback%> modifier");
+ return list;
+ }
+ c_parser_consume_token (parser);
+ if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+ return list;
+ p = "";
+ if (c_parser_next_token_is (parser, CPP_NAME))
+ p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+ if (strcmp (p, "abort") == 0)
+ kind = OMP_CLAUSE_FALLBACK_ABORT;
+ else if (strcmp (p, "default_mem") == 0)
+ kind = OMP_CLAUSE_FALLBACK_DEFAULT_MEM;
+ else if (strcmp (p, "null") == 0)
+ kind = OMP_CLAUSE_FALLBACK_NULL;
+ else
+ {
+ c_parser_error (parser, "expected %<abort%>, %<default_mem%>, or "
+ "%<null%> as fallback mode");
+ return list;
+ }
+ c_parser_consume_token (parser);
+ if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
+ return list;
+ if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
+ return list;
+ }
+ 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);
+ tree size = c_fully_fold (expr.value, false, NULL);
+ parens.skip_until_found_close (parser);
+
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (size)))
+ {
+ error_at (expr_loc, "expected integer expression");
+ return list;
+ }
+
+ /* Attempt to statically determine when the number is negative. */
+ tree c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, size,
+ build_int_cst (TREE_TYPE (size), 0));
+ protected_set_expr_location (c, expr_loc);
+ if (c == boolean_true_node)
+ {
+ warning_at (expr_loc, OPT_Wopenmp,
+ "%<dyn_groupprivate%> value must be non-negative");
+ size = integer_zero_node;
+ }
+ check_no_duplicate_clause (list, OMP_CLAUSE_DYN_GROUPPRIVATE,
+ "dyn_groupprivate");
+
+ c = build_omp_clause (clause_loc, OMP_CLAUSE_DYN_GROUPPRIVATE);
+ OMP_CLAUSE_DYN_GROUPPRIVATE_KIND (c) = kind;
+ OMP_CLAUSE_DYN_GROUPPRIVATE_EXPR (c) = size;
+ OMP_CLAUSE_CHAIN (c) = list;
+ list = c;
+
+ return list;
+}
+
/* OpenMP 4.0:
map ( map-kind: variable-list )
map ( variable-list )
clauses = c_parser_omp_clause_destroy (parser, clauses);
c_name = "destroy";
break;
+ case PRAGMA_OMP_CLAUSE_DYN_GROUPPRIVATE:
+ clauses = c_parser_omp_clause_dyn_groupprivate (parser, clauses);
+ c_name = "dyn_groupprivate";
+ break;
case PRAGMA_OMP_CLAUSE_INIT:
clauses = c_parser_omp_clause_init (parser, clauses);
c_name = "init";
structured-block */
#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_ALLOCATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DYN_GROUPPRIVATE) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
| (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_HAS_DEVICE_ADDR))
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT))
static bool
c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
case OMP_CLAUSE_FINAL:
case OMP_CLAUSE_DEVICE:
case OMP_CLAUSE_DIST_SCHEDULE:
+ case OMP_CLAUSE_DYN_GROUPPRIVATE:
case OMP_CLAUSE_PARALLEL:
case OMP_CLAUSE_FOR:
case OMP_CLAUSE_SECTIONS:
result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
else if (!strcmp ("doacross", p))
result = PRAGMA_OMP_CLAUSE_DOACROSS;
+ else if (!strcmp ("dyn_groupprivate", p))
+ result = PRAGMA_OMP_CLAUSE_DYN_GROUPPRIVATE;
break;
case 'e':
if (!strcmp ("enter", p))
return nl;
}
+/* OpenMP 6.1:
+ dyn_groupprivate ( [fallback-modifier : ] integer-expression )
+
+ fallback-modifier
+ fallback( abort | default_mem | null ) */
+
+static tree
+cp_parser_omp_clause_dyn_groupprivate (cp_parser *parser, tree list,
+ location_t location)
+{
+ matching_parens parens;
+ if (!parens.require_open (parser))
+ return list;
+
+ enum omp_clause_fallback_kind kind = OMP_CLAUSE_FALLBACK_UNSPECIFIED;
+
+ size_t n;
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
+ && (cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON)
+ || (cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN)
+ && (n = cp_parser_skip_balanced_tokens (parser, 2)) != 3
+ && cp_lexer_nth_token_is (parser->lexer, n, CPP_COLON))))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ if (strcmp (IDENTIFIER_POINTER (id), "fallback") != 0)
+ {
+ cp_parser_error (parser, "expected %<fallback%> modifier");
+ cp_parser_skip_to_closing_parenthesis (parser,
+ /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ return list;
+ }
+ cp_lexer_consume_token (parser->lexer);
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+ const char *p = "";
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ id = cp_lexer_peek_token (parser->lexer)->u.value;
+ p = IDENTIFIER_POINTER (id);
+ }
+ if (strcmp (p, "abort") == 0)
+ kind = OMP_CLAUSE_FALLBACK_ABORT;
+ else if (strcmp (p, "default_mem") == 0)
+ kind = OMP_CLAUSE_FALLBACK_DEFAULT_MEM;
+ else if (strcmp (p, "null") == 0)
+ kind = OMP_CLAUSE_FALLBACK_NULL;
+ else
+ {
+ cp_parser_error (parser, "expected %<abort%>, %<default_mem%>, or "
+ "%<null%> as fallback mode");
+ cp_parser_skip_to_closing_parenthesis (parser,
+ /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ return list;
+ }
+ cp_lexer_consume_token (parser->lexer);
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ return list;
+ if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
+ return list;
+ }
+
+ tree size = cp_parser_assignment_expression (parser);
+
+ if (size == error_mark_node
+ || !parens.require_close (parser))
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+
+ check_no_duplicate_clause (list, OMP_CLAUSE_DYN_GROUPPRIVATE,
+ "dyn_groupprivate", location);
+
+ tree c = build_omp_clause (location, OMP_CLAUSE_DYN_GROUPPRIVATE);
+ OMP_CLAUSE_DYN_GROUPPRIVATE_KIND (c) = kind;
+ OMP_CLAUSE_DYN_GROUPPRIVATE_EXPR (c) = size;
+ OMP_CLAUSE_CHAIN (c) = list;
+ list = c;
+
+ return list;
+}
+
/* OpenMP 4.0:
map ( map-kind : variable-list )
map ( variable-list )
clauses);
c_name = "destroy";
break;
+ case PRAGMA_OMP_CLAUSE_DYN_GROUPPRIVATE:
+ clauses = cp_parser_omp_clause_dyn_groupprivate (parser, clauses,
+ token->location);
+ c_name = "dyn_groupprivate";
+ break;
case PRAGMA_OMP_CLAUSE_INIT:
{
/* prefer_type parsing fails often such that many follow-up errors
structured-block */
#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_ALLOCATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DYN_GROUPPRIVATE) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR) \
| (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_IF) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT))
static bool
cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok,
case OMP_CLAUSE_ASYNC:
case OMP_CLAUSE_WAIT:
case OMP_CLAUSE_DETACH:
+ case OMP_CLAUSE_DYN_GROUPPRIVATE:
OMP_CLAUSE_OPERAND (nc, 0)
= tsubst_stmt (OMP_CLAUSE_OPERAND (oc, 0), args, complain, in_decl);
break;
case OMP_CLAUSE_NUM_THREADS:
case OMP_CLAUSE_NUM_GANGS:
case OMP_CLAUSE_NUM_WORKERS:
+ case OMP_CLAUSE_DYN_GROUPPRIVATE:
case OMP_CLAUSE_VECTOR_LENGTH:
t = OMP_CLAUSE_OPERAND (c, 0);
if (t == error_mark_node)
if (!processing_template_decl)
{
t = maybe_constant_value (t);
- if (TREE_CODE (t) == INTEGER_CST
+ if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DYN_GROUPPRIVATE
+ && TREE_CODE (t) == INTEGER_CST
&& tree_int_cst_sgn (t) != 1)
{
switch (OMP_CLAUSE_CODE (c))
}
t = integer_one_node;
}
+ else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DYN_GROUPPRIVATE
+ && TREE_CODE (t) == INTEGER_CST
+ && tree_int_cst_sgn (t) < 0)
+ {
+ warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
+ "%<dyn_groupprivate%> value must be "
+ "non-negative");
+ t = integer_zero_node;
+ }
t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
}
OMP_CLAUSE_OPERAND (c, 0) = t;
if (omp_clauses->num_threads)
resolve_positive_int_expr (omp_clauses->num_threads, "NUM_THREADS");
if (omp_clauses->dyn_groupprivate)
- resolve_positive_int_expr (omp_clauses->dyn_groupprivate,
- "DYN_GROUPPRIVATE");
+ resolve_nonnegative_int_expr (omp_clauses->dyn_groupprivate,
+ "DYN_GROUPPRIVATE");
if (omp_clauses->chunk_size)
{
gfc_expr *expr = omp_clauses->chunk_size;
if (clauses->dyn_groupprivate)
{
- sorry_at (gfc_get_location (&where), "%<dyn_groupprivate%> clause");
-#if 0 /* FIXME: Handle it, including 'fallback(abort/default_mem/null)' */
- tree dyn_groupprivate;
-
gfc_init_se (&se, NULL);
gfc_conv_expr (&se, clauses->dyn_groupprivate);
gfc_add_block_to_block (block, &se.pre);
- dyn_groupprivate = gfc_evaluate_now (se.expr, block);
+ tree expr = (CONSTANT_CLASS_P (se.expr) || DECL_P (se.expr)
+ ? se.expr : gfc_evaluate_now (se.expr, block));
gfc_add_block_to_block (block, &se.post);
+ enum omp_clause_fallback_kind kind = OMP_CLAUSE_FALLBACK_UNSPECIFIED;
+ switch (clauses->fallback)
+ {
+ case OMP_FALLBACK_ABORT:
+ kind = OMP_CLAUSE_FALLBACK_ABORT;
+ break;
+ case OMP_FALLBACK_DEFAULT_MEM:
+ kind = OMP_CLAUSE_FALLBACK_DEFAULT_MEM;
+ break;
+ case OMP_FALLBACK_NULL:
+ kind = OMP_CLAUSE_FALLBACK_NULL;
+ break;
+ case OMP_FALLBACK_NONE:
+ break;
+ }
c = build_omp_clause (gfc_get_location (&where),
OMP_CLAUSE_DYN_GROUPPRIVATE);
- OMP_CLAUSE_NUM_THREADS_EXPR (c) = num_threads;
+ OMP_CLAUSE_DYN_GROUPPRIVATE_KIND (c) = kind;
+ OMP_CLAUSE_DYN_GROUPPRIVATE_EXPR (c) = expr;
omp_clauses = gfc_trans_add_clause (c, omp_clauses);
-#endif
}
chunk_size = NULL_TREE;
case OMP_CLAUSE_DESTROY:
break;
+ case OMP_CLAUSE_DYN_GROUPPRIVATE:
+ remove = true;
+ sorry_at (OMP_CLAUSE_LOCATION (c),"%<dyn_groupprivate%> clause");
+ break;
+
case OMP_CLAUSE_ORDER:
ctx->order_concurrent = true;
break;
--- /dev/null
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-original" } */
+
+void f()
+{
+ int N = 1024;
+
+ #pragma omp target dyn_groupprivate(1024) // { dg-message "sorry, unimplemented: 'dyn_groupprivate' clause" }
+ ;
+
+ #pragma omp target dyn_groupprivate (1024 * N) // { dg-message "sorry, unimplemented: 'dyn_groupprivate' clause" }
+ ;
+
+ #pragma omp target dyn_groupprivate ( fallback ( abort ) : N) // { dg-message "sorry, unimplemented: 'dyn_groupprivate' clause" }
+ ;
+
+ #pragma omp target dyn_groupprivate ( fallback ( null ) : N) // { dg-message "sorry, unimplemented: 'dyn_groupprivate' clause" }
+ ;
+
+ #pragma omp target dyn_groupprivate ( fallback ( default_mem ) : N) // { dg-message "sorry, unimplemented: 'dyn_groupprivate' clause" }
+ ;
+}
+
+/* { dg-final { scan-tree-dump-times "#pragma omp target dyn_groupprivate\\(1024\\)" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp target dyn_groupprivate\\(N \\* 1024\\)" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp target dyn_groupprivate\\(fallback\\(abort\\):N\\)" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp target dyn_groupprivate\\(fallback\\(null\\):N\\)" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp target dyn_groupprivate\\(fallback\\(default_mem\\):N\\)" 1 "original" } } */
--- /dev/null
+/* { dg-do compile } */
+
+void f()
+{
+#if !defined(__cplusplus) || __cplusplus >= 201103L
+ constexpr int M = 1024; // C20 + C++11
+#endif
+ int N, A[1];
+ N = 1024;
+
+ #pragma omp target dyn_groupprivate(0)
+ ;
+
+ #pragma omp target dyn_groupprivate(0) dyn_groupprivate(0) // { dg-error "too many 'dyn_groupprivate' clauses" }
+ ;
+
+ #pragma omp target dyn_groupprivate(1,) // { dg-error "expected '\\)' before ',' token" }
+ ;
+
+ #pragma omp target dyn_groupprivate(-123) // { dg-warning "'dyn_groupprivate' value must be non-negative \\\[-Wopenmp\\\]" }
+ ;
+
+#if !defined(__cplusplus) || __cplusplus >= 201103L
+ #pragma omp target dyn_groupprivate (0 * M - 1) // { dg-warning "'dyn_groupprivate' value must be non-negative \\\[-Wopenmp\\\]" "" { target { ! c++98_only } } }
+#endif
+ ;
+
+ #pragma omp target dyn_groupprivate (- 4) // { dg-warning "'dyn_groupprivate' value must be non-negative \\\[-Wopenmp\\\]" }
+ ;
+
+ #pragma omp target dyn_groupprivate ( fallback ( other ) : N) // { dg-error "expected 'abort', 'default_mem', or 'null' as fallback mode before 'other'" }
+ // { dg-error "expected an OpenMP clause before ':' token" "" { target c++ } .-1 }
+ ;
+
+ #pragma omp target dyn_groupprivate ( A )
+ // { dg-error "expected integer expression" "" { target c } .-1 }
+ // { dg-error "'dyn_groupprivate' expression must be integral" "" { target c++ } .-2 }
+ ;
+
+ #pragma omp target dyn_groupprivate ( 1024. )
+ // { dg-error "expected integer expression" "" { target c } .-1 }
+ // { dg-error "'dyn_groupprivate' expression must be integral" "" { target c++ } .-2 }
+ ;
+
+ #pragma omp target dyn_groupprivate ( foo ( 4 ) : 10 ) // { dg-error "expected 'fallback' modifier before 'foo'" }
+ ;
+
+ #pragma omp target dyn_groupprivate ( foo2 ( ) : 10 ) // { dg-error "expected 'fallback' modifier before 'foo2'" }
+ ;
+
+ #pragma omp target dyn_groupprivate ( fallback ( ) : 10 ) // { dg-error "expected 'abort', 'default_mem', or 'null' as fallback mode before '\\)'" }
+ // { dg-error "expected an OpenMP clause before ':' token" "" { target c++ } .-1 }
+ ;
+
+ #pragma omp target dyn_groupprivate ( bar : 10 ) // { dg-error "expected 'fallback' modifier before 'bar'" }
+ ;
+
+ #pragma omp target dyn_groupprivate ( fallback : 10 ) // { dg-error "expected '\\(' before ':' token" }
+ // { dg-error "expected an OpenMP clause before ':' token" "" { target c++ } .-1 }
+ ;
+
+ #pragma omp target dyn_groupprivate ( fallback ( null,) : 10 ) // { dg-error "expected '\\)' before ',' token" }
+ // { dg-error "expected an OpenMP clause before '\\)' token" "" { target c++ } .-1 }
+ ;
+}
+
+// { dg-message "sorry, unimplemented: 'dyn_groupprivate' clause" "" { target *-*-* } 11 }
+// { dg-message "sorry, unimplemented: 'dyn_groupprivate' clause" "" { target *-*-* } 14 }
+// { dg-message "sorry, unimplemented: 'dyn_groupprivate' clause" "" { target *-*-* } 17 }
+// { dg-message "sorry, unimplemented: 'dyn_groupprivate' clause" "" { target *-*-* } 20 }
+// { dg-message "sorry, unimplemented: 'dyn_groupprivate' clause" "" { target { ! c++98_only } } 24 }
+// { dg-message "sorry, unimplemented: 'dyn_groupprivate' clause" "" { target *-*-* } 28 }
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-original" }
+
implicit none
integer :: N
!$omp target dyn_groupprivate ( fallback ( default_mem ) : N) ! { dg-message "sorry, unimplemented: 'dyn_groupprivate' clause" }
!$omp end target
end
+
+! { dg-final { scan-tree-dump-times "#pragma omp target dyn_groupprivate\\(1024\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp target dyn_groupprivate\\(D.4680\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp target dyn_groupprivate\\(fallback\\(abort\\):n\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp target dyn_groupprivate\\(fallback\\(null\\):n\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp target dyn_groupprivate\\(fallback\\(default_mem\\):n\\)" 1 "original" } }
+! { dg-do compile }
+
implicit none
integer, parameter :: M = 1024
N = 1024
-!$omp target dyn_groupprivate(-123) ! { dg-warning "INTEGER expression of DYN_GROUPPRIVATE clause at .1. must be positive \\\[-Wopenmp\\\]" }
+!$omp target dyn_groupprivate(0) ! OK, zero is permitted
+block; end block
+
+!$omp target dyn_groupprivate(0) dyn_groupprivate(0) ! { dg-error "Duplicated 'dyn_groupprivate' clause" }
+block; end block
+
+!$omp target dyn_groupprivate(-123) ! { dg-warning "INTEGER expression of DYN_GROUPPRIVATE clause at .1. must be non-negative \\\[-Wopenmp\\\]" }
block; end block
-!$omp target dyn_groupprivate (0 * M) ! { dg-warning "INTEGER expression of DYN_GROUPPRIVATE clause at .1. must be positive \\\[-Wopenmp\\\]" }
+!$omp target dyn_groupprivate (0 * M-1) ! { dg-warning "INTEGER expression of DYN_GROUPPRIVATE clause at .1. must be non-negative \\\[-Wopenmp\\\]" }
block; end block
!$omp target dyn_groupprivate ( fallback ( other ) : N) ! { dg-error "Failed to match clause" }
/* OpenMP clause: nocontext (scalar-expression). */
OMP_CLAUSE_NOCONTEXT,
+ /* OpenMP clause: dyn_groupprivate ( [fallback (...)] : integer-expression). */
+ OMP_CLAUSE_DYN_GROUPPRIVATE,
};
#undef DEFTREESTRUCT
OMP_CLAUSE_BIND_THREAD
};
+enum omp_clause_fallback_kind {
+ OMP_CLAUSE_FALLBACK_UNSPECIFIED,
+ OMP_CLAUSE_FALLBACK_ABORT,
+ OMP_CLAUSE_FALLBACK_DEFAULT_MEM,
+ OMP_CLAUSE_FALLBACK_NULL
+};
+
+
/* memory-order-clause on OpenMP atomic/flush constructs or
argument of atomic_default_mem_order clause. */
enum omp_memory_order {
enum omp_clause_defaultmap_kind defaultmap_kind;
enum omp_clause_bind_kind bind_kind;
enum omp_clause_device_type_kind device_type_kind;
+ enum omp_clause_fallback_kind fallback_kind;
} GTY ((skip)) subcode;
/* The gimplification of OMP_CLAUSE_REDUCTION_{INIT,MERGE} for omp-low's
case OMP_CLAUSE_DEPEND:
case OMP_CLAUSE_DOACROSS:
case OMP_CLAUSE_DEVICE:
+ case OMP_CLAUSE_DYN_GROUPPRIVATE:
case OMP_CLAUSE_NUM_TEAMS:
case OMP_CLAUSE_THREAD_LIMIT:
case OMP_CLAUSE_SAFELEN:
case OMP_CLAUSE_DEPEND:
case OMP_CLAUSE_DOACROSS:
case OMP_CLAUSE_DEVICE:
+ case OMP_CLAUSE_DYN_GROUPPRIVATE:
case OMP_CLAUSE_NUM_TEAMS:
case OMP_CLAUSE_THREAD_LIMIT:
case OMP_CLAUSE_SAFELEN:
pp_right_paren (pp);
break;
+ case OMP_CLAUSE_DYN_GROUPPRIVATE:
+ pp_string (pp, "dyn_groupprivate(");
+ switch (OMP_CLAUSE_DYN_GROUPPRIVATE_KIND (clause))
+ {
+ case OMP_CLAUSE_FALLBACK_ABORT:
+ pp_string (pp, "fallback(abort):");
+ break;
+ case OMP_CLAUSE_FALLBACK_DEFAULT_MEM:
+ pp_string (pp, "fallback(default_mem):");
+ break;
+ case OMP_CLAUSE_FALLBACK_NULL:
+ pp_string (pp, "fallback(null):");
+ break;
+ case OMP_CLAUSE_FALLBACK_UNSPECIFIED:
+ break;
+ }
+ dump_generic_node (pp, OMP_CLAUSE_DYN_GROUPPRIVATE_EXPR (clause),
+ spc, flags, false);
+ pp_right_paren (pp);
+ break;
+
case OMP_CLAUSE_SAFELEN:
pp_string (pp, "safelen(");
dump_generic_node (pp, OMP_CLAUSE_SAFELEN_EXPR (clause),
0, /* OMP_CLAUSE_NOHOST */
1, /* OMP_CLAUSE_NOVARIANTS */
1, /* OMP_CLAUSE_NOCONTEXT */
+ 1, /* OMP_CLAUSE_DYN_GROUPPRIVATE */
};
const char * const omp_clause_code_name[] =
"nohost",
"novariants",
"nocontext",
+ "dyn_groupprivate",
};
/* Unless specific to OpenACC, we tend to internally maintain OpenMP-centric
#define OMP_CLAUSE_BIND_KIND(NODE) \
(OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_BIND)->omp_clause.subcode.bind_kind)
+#define OMP_CLAUSE_DYN_GROUPPRIVATE_EXPR(NODE) \
+ OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DYN_GROUPPRIVATE), 0)
+#define OMP_CLAUSE_DYN_GROUPPRIVATE_KIND(NODE) \
+ (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DYN_GROUPPRIVATE)->omp_clause.subcode.fallback_kind)
+
/* True if ENTER clause is spelled as TO. */
#define OMP_CLAUSE_ENTER_TO(NODE) \
(OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_ENTER)->base.public_flag)