On 10/27/15 00:59, Jakub Jelinek wrote:
On Mon, Oct 26, 2015 at 03:35:20PM -0700, Cesar Philippidis wrote:
I used that generic message for all of those clauses except for _GANG,
_WORKER and _VECTOR. The gang clause, at the very least, needed it to
disambiguate the static and num arguments. If you want I can handle
_WORKER and _VECTOR with the generic message. I only included it because
those arguments are optional, whereas they are mandatory for the other
clauses.
Is this patch OK for trunk?
Ok.
this is the patch that I've committed.
nathan
2015-10-27 Cesar Philippidis <ce...@codesourcery.com>
Thomas Schwinge <tho...@codesourcery.com>
James Norris <jnor...@codesourcery.com>
Joseph Myers <jos...@codesourcery.com>
Julian Brown <jul...@codesourcery.com>
Nathan Sidwell <nat...@codesourcery.com>
Bernd Schmidt <bschm...@redhat.com>
gcc/cp/
* parser.c (cp_parser_omp_clause_name): Add auto, gang, seq,
vector, worker.
(cp_parser_oacc_simple_clause): New.
(cp_parser_oacc_shape_clause): New.
(cp_parser_oacc_all_clauses): Add auto, gang, seq, vector, worker.
(OACC_LOOP_CLAUSE_MASK): Likewise.
* semantics.c (finish_omp_clauses): Add auto, gang, seq, vector,
worker. Unify the handling of teams, tasks and vector_length with
the other loop shape clauses.
2015-10-27 Nathan Sidwell <nat...@codesourcery.com>
Cesar Philippidis <ce...@codesourcery.com>
gcc/testsuite/
* g++.dg/g++.dg/gomp/pr33372-1.C: Adjust diagnostic.
* gcc/testsuite/g++.dg/gomp/pr33372-3.C: Likewise.
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c (revision 229443)
+++ gcc/cp/semantics.c (working copy)
@@ -5965,14 +5965,76 @@ finish_omp_clauses (tree clauses, bool a
OMP_CLAUSE_FINAL_EXPR (c) = t;
break;
+ case OMP_CLAUSE_GANG:
+ /* Operand 1 is the gang static: argument. */
+ t = OMP_CLAUSE_OPERAND (c, 1);
+ if (t != NULL_TREE)
+ {
+ if (t == error_mark_node)
+ remove = true;
+ else if (!type_dependent_expression_p (t)
+ && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
+ {
+ error ("%<gang%> static 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
+ && t != integer_minus_one_node)
+ {
+ warning_at (OMP_CLAUSE_LOCATION (c), 0,
+ "%<gang%> static value must be"
+ "positive");
+ t = integer_one_node;
+ }
+ }
+ t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
+ }
+ OMP_CLAUSE_OPERAND (c, 1) = t;
+ }
+ /* Check operand 0, the num argument. */
+
+ case OMP_CLAUSE_WORKER:
+ case OMP_CLAUSE_VECTOR:
+ if (OMP_CLAUSE_OPERAND (c, 0) == NULL_TREE)
+ break;
+
+ case OMP_CLAUSE_NUM_TASKS:
+ case OMP_CLAUSE_NUM_TEAMS:
case OMP_CLAUSE_NUM_THREADS:
- t = OMP_CLAUSE_NUM_THREADS_EXPR (c);
+ case OMP_CLAUSE_NUM_GANGS:
+ case OMP_CLAUSE_NUM_WORKERS:
+ case OMP_CLAUSE_VECTOR_LENGTH:
+ t = OMP_CLAUSE_OPERAND (c, 0);
if (t == error_mark_node)
remove = true;
else if (!type_dependent_expression_p (t)
&& !INTEGRAL_TYPE_P (TREE_TYPE (t)))
{
- error ("num_threads expression must be integral");
+ switch (OMP_CLAUSE_CODE (c))
+ {
+ case OMP_CLAUSE_GANG:
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%<gang%> num expression must be integral"); break;
+ case OMP_CLAUSE_VECTOR:
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%<vector%> length expression must be integral");
+ break;
+ case OMP_CLAUSE_WORKER:
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%<worker%> num expression must be integral");
+ break;
+ default:
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qs expression must be integral",
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ }
remove = true;
}
else
@@ -5984,13 +6046,33 @@ finish_omp_clauses (tree clauses, bool a
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");
+ switch (OMP_CLAUSE_CODE (c))
+ {
+ case OMP_CLAUSE_GANG:
+ warning_at (OMP_CLAUSE_LOCATION (c), 0,
+ "%<gang%> num value must be positive");
+ break;
+ case OMP_CLAUSE_VECTOR:
+ warning_at (OMP_CLAUSE_LOCATION (c), 0,
+ "%<vector%> length value must be"
+ "positive");
+ break;
+ case OMP_CLAUSE_WORKER:
+ warning_at (OMP_CLAUSE_LOCATION (c), 0,
+ "%<worker%> num value must be"
+ "positive");
+ break;
+ default:
+ warning_at (OMP_CLAUSE_LOCATION (c), 0,
+ "%qs value must be positive",
+ omp_clause_code_name
+ [OMP_CLAUSE_CODE (c)]);
+ }
t = integer_one_node;
}
t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
}
- OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
+ OMP_CLAUSE_OPERAND (c, 0) = t;
}
break;
@@ -6062,35 +6144,6 @@ finish_omp_clauses (tree clauses, bool a
}
break;
- case OMP_CLAUSE_NUM_TEAMS:
- t = OMP_CLAUSE_NUM_TEAMS_EXPR (c);
- if (t == error_mark_node)
- remove = true;
- else if (!type_dependent_expression_p (t)
- && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
- {
- error ("%<num_teams%> 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_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;
-
case OMP_CLAUSE_ASYNC:
t = OMP_CLAUSE_ASYNC_EXPR (c);
if (t == error_mark_node)
@@ -6110,16 +6163,6 @@ finish_omp_clauses (tree clauses, bool a
}
break;
- case OMP_CLAUSE_VECTOR_LENGTH:
- t = OMP_CLAUSE_VECTOR_LENGTH_EXPR (c);
- t = maybe_convert_cond (t);
- if (t == error_mark_node)
- remove = true;
- else if (!processing_template_decl)
- t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
- OMP_CLAUSE_VECTOR_LENGTH_EXPR (c) = t;
- break;
-
case OMP_CLAUSE_WAIT:
t = OMP_CLAUSE_WAIT_EXPR (c);
if (t == error_mark_node)
@@ -6547,35 +6590,6 @@ finish_omp_clauses (tree clauses, bool a
}
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)
@@ -6694,6 +6708,8 @@ finish_omp_clauses (tree clauses, bool a
case OMP_CLAUSE_SIMD:
case OMP_CLAUSE_DEFAULTMAP:
case OMP_CLAUSE__CILK_FOR_COUNT_:
+ case OMP_CLAUSE_AUTO:
+ case OMP_CLAUSE_SEQ:
break;
case OMP_CLAUSE_INBRANCH:
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c (revision 229443)
+++ gcc/cp/parser.c (working copy)
@@ -29064,7 +29064,9 @@ cp_parser_omp_clause_name (cp_parser *pa
{
pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
- if (cp_lexer_next_token_is_keyword (parser->lexer, RID_IF))
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO))
+ result = PRAGMA_OACC_CLAUSE_AUTO;
+ else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_IF))
result = PRAGMA_OMP_CLAUSE_IF;
else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DEFAULT))
result = PRAGMA_OMP_CLAUSE_DEFAULT;
@@ -29122,7 +29124,9 @@ cp_parser_omp_clause_name (cp_parser *pa
result = PRAGMA_OMP_CLAUSE_FROM;
break;
case 'g':
- if (!strcmp ("grainsize", p))
+ if (!strcmp ("gang", p))
+ result = PRAGMA_OACC_CLAUSE_GANG;
+ else if (!strcmp ("grainsize", p))
result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
break;
case 'h':
@@ -29212,6 +29216,8 @@ cp_parser_omp_clause_name (cp_parser *pa
result = PRAGMA_OMP_CLAUSE_SECTIONS;
else if (!strcmp ("self", p))
result = PRAGMA_OACC_CLAUSE_SELF;
+ else if (!strcmp ("seq", p))
+ result = PRAGMA_OACC_CLAUSE_SEQ;
else if (!strcmp ("shared", p))
result = PRAGMA_OMP_CLAUSE_SHARED;
else if (!strcmp ("simd", p))
@@ -29238,7 +29244,9 @@ cp_parser_omp_clause_name (cp_parser *pa
result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
break;
case 'v':
- if (!strcmp ("vector_length", p))
+ if (!strcmp ("vector", p))
+ result = PRAGMA_OACC_CLAUSE_VECTOR;
+ else if (!strcmp ("vector_length", p))
result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
else if (flag_cilkplus && !strcmp ("vectorlength", p))
result = PRAGMA_CILK_CLAUSE_VECTORLENGTH;
@@ -29246,6 +29254,8 @@ cp_parser_omp_clause_name (cp_parser *pa
case 'w':
if (!strcmp ("wait", p))
result = PRAGMA_OACC_CLAUSE_WAIT;
+ else if (!strcmp ("worker", p))
+ result = PRAGMA_OACC_CLAUSE_WORKER;
break;
}
}
@@ -29582,6 +29592,146 @@ cp_parser_oacc_data_clause_deviceptr (cp
return list;
}
+/* OpenACC 2.0:
+ auto
+ independent
+ nohost
+ seq */
+
+static tree
+cp_parser_oacc_simple_clause (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;
+}
+
+/* OpenACC:
+
+ gang [( gang-arg-list )]
+ worker [( [num:] int-expr )]
+ vector [( [length:] int-expr )]
+
+ where gang-arg is one of:
+
+ [num:] int-expr
+ static: size-expr
+
+ and size-expr may be:
+
+ *
+ int-expr
+*/
+
+static tree
+cp_parser_oacc_shape_clause (cp_parser *parser, omp_clause_code kind,
+ const char *str, tree list)
+{
+ const char *id = "num";
+ cp_lexer *lexer = parser->lexer;
+ tree ops[2] = { NULL_TREE, NULL_TREE }, c;
+ location_t loc = cp_lexer_peek_token (lexer)->location;
+
+ if (kind == OMP_CLAUSE_VECTOR)
+ id = "length";
+
+ if (cp_lexer_next_token_is (lexer, CPP_OPEN_PAREN))
+ {
+ cp_lexer_consume_token (lexer);
+
+ do
+ {
+ cp_token *next = cp_lexer_peek_token (lexer);
+ int idx = 0;
+
+ /* Gang static argument. */
+ if (kind == OMP_CLAUSE_GANG
+ && cp_lexer_next_token_is_keyword (lexer, RID_STATIC))
+ {
+ cp_lexer_consume_token (lexer);
+
+ if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
+ goto cleanup_error;
+
+ idx = 1;
+ if (ops[idx] != NULL)
+ {
+ cp_parser_error (parser, "too many %<static%> arguments");
+ goto cleanup_error;
+ }
+
+ /* Check for the '*' argument. */
+ if (cp_lexer_next_token_is (lexer, CPP_MULT))
+ {
+ cp_lexer_consume_token (lexer);
+ ops[idx] = integer_minus_one_node;
+
+ if (cp_lexer_next_token_is (lexer, CPP_COMMA))
+ {
+ cp_lexer_consume_token (lexer);
+ continue;
+ }
+ else break;
+ }
+ }
+ /* Worker num: argument and vector length: arguments. */
+ else if (cp_lexer_next_token_is (lexer, CPP_NAME)
+ && strcmp (id, IDENTIFIER_POINTER (next->u.value)) == 0
+ && cp_lexer_nth_token_is (lexer, 2, CPP_COLON))
+ {
+ cp_lexer_consume_token (lexer); /* id */
+ cp_lexer_consume_token (lexer); /* ':' */
+ }
+
+ /* Now collect the actual argument. */
+ if (ops[idx] != NULL_TREE)
+ {
+ cp_parser_error (parser, "unexpected argument");
+ goto cleanup_error;
+ }
+
+ tree expr = cp_parser_assignment_expression (parser, NULL, false,
+ false);
+ if (expr == error_mark_node)
+ goto cleanup_error;
+
+ mark_exp_read (expr);
+ ops[idx] = expr;
+
+ if (kind == OMP_CLAUSE_GANG
+ && cp_lexer_next_token_is (lexer, CPP_COMMA))
+ {
+ cp_lexer_consume_token (lexer);
+ continue;
+ }
+ break;
+ }
+ while (1);
+
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ goto cleanup_error;
+ }
+
+ check_no_duplicate_clause (list, kind, str, loc);
+
+ c = build_omp_clause (loc, kind);
+
+ if (ops[1])
+ OMP_CLAUSE_OPERAND (c, 1) = ops[1];
+
+ OMP_CLAUSE_OPERAND (c, 0) = ops[0];
+ OMP_CLAUSE_CHAIN (c) = list;
+
+ return c;
+
+ cleanup_error:
+ cp_parser_skip_to_closing_parenthesis (parser, false, false, true);
+ return list;
+}
+
/* OpenACC:
vector_length ( expression ) */
@@ -31306,6 +31456,11 @@ cp_parser_oacc_all_clauses (cp_parser *p
clauses = cp_parser_oacc_clause_async (parser, clauses);
c_name = "async";
break;
+ case PRAGMA_OACC_CLAUSE_AUTO:
+ clauses = cp_parser_oacc_simple_clause (parser, OMP_CLAUSE_AUTO,
+ clauses, here);
+ c_name = "auto";
+ break;
case PRAGMA_OACC_CLAUSE_COLLAPSE:
clauses = cp_parser_omp_clause_collapse (parser, clauses, here);
c_name = "collapse";
@@ -31338,6 +31493,11 @@ cp_parser_oacc_all_clauses (cp_parser *p
clauses = cp_parser_oacc_data_clause_deviceptr (parser, clauses);
c_name = "deviceptr";
break;
+ case PRAGMA_OACC_CLAUSE_GANG:
+ c_name = "gang";
+ clauses = cp_parser_oacc_shape_clause (parser, OMP_CLAUSE_GANG,
+ c_name, clauses);
+ break;
case PRAGMA_OACC_CLAUSE_HOST:
clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
c_name = "host";
@@ -31382,6 +31542,16 @@ cp_parser_oacc_all_clauses (cp_parser *p
clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
c_name = "self";
break;
+ case PRAGMA_OACC_CLAUSE_SEQ:
+ clauses = cp_parser_oacc_simple_clause (parser, OMP_CLAUSE_SEQ,
+ clauses, here);
+ c_name = "seq";
+ break;
+ case PRAGMA_OACC_CLAUSE_VECTOR:
+ c_name = "vector";
+ clauses = cp_parser_oacc_shape_clause (parser, OMP_CLAUSE_VECTOR,
+ c_name, clauses);
+ break;
case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
clauses = cp_parser_oacc_clause_vector_length (parser, clauses);
c_name = "vector_length";
@@ -31390,6 +31560,11 @@ cp_parser_oacc_all_clauses (cp_parser *p
clauses = cp_parser_oacc_clause_wait (parser, clauses);
c_name = "wait";
break;
+ case PRAGMA_OACC_CLAUSE_WORKER:
+ c_name = "worker";
+ clauses = cp_parser_oacc_shape_clause (parser, OMP_CLAUSE_WORKER,
+ c_name, clauses);
+ break;
default:
cp_parser_error (parser, "expected %<#pragma acc%> clause");
goto saw_error;
@@ -34303,6 +34478,11 @@ cp_parser_oacc_enter_exit_data (cp_parse
#define OACC_LOOP_CLAUSE_MASK \
( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) )
static tree
Index: gcc/testsuite/g++.dg/gomp/pr33372-3.C
===================================================================
--- gcc/testsuite/g++.dg/gomp/pr33372-3.C (revision 229443)
+++ gcc/testsuite/g++.dg/gomp/pr33372-3.C (working copy)
@@ -6,7 +6,7 @@ template <typename T>
void f ()
{
T n = 6;
-#pragma omp parallel num_threads(n) // { dg-error "num_threads expression must be integral" }
+#pragma omp parallel num_threads(n) // { dg-error "'num_threads' expression must be integral" }
;
#pragma omp parallel for schedule(static, n)
for (int i = 0; i < 10; i++) // { dg-error "chunk size expression must be integral" }
Index: gcc/testsuite/g++.dg/gomp/pr33372-1.C
===================================================================
--- gcc/testsuite/g++.dg/gomp/pr33372-1.C (revision 229443)
+++ gcc/testsuite/g++.dg/gomp/pr33372-1.C (working copy)
@@ -6,7 +6,7 @@ template <typename T>
void f ()
{
extern T n ();
-#pragma omp parallel num_threads(n) // { dg-error "num_threads expression must be integral" }
+#pragma omp parallel num_threads(n) // { dg-error "'num_threads' expression must be integral" }
;
#pragma omp parallel for schedule(static, n)
for (int i = 0; i < 10; i++) // { dg-error "chunk size expression must be integral" }