This patch implements changes to the C parser to deal with the 'gang',
'worker', 'vector', 'seq' and 'auto' clauses on an OpenACC loop directive.
The first 3 can take a numeric argument, which is used within a kernels offload
region and the gang clause can take an additional 'static' argument, to force
static loop iteration assignment.
nathan
2015-10-20 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>
* c-parser.c (c_parser_oacc_shape_clause): New.
(c_parser_oacc_simple_clause): New.
(c_parser_oacc_all_clauses): Add auto, gang, seq, vector, worker.
(OACC_LOOP_CLAUSE_MASK): Add gang, worker, vector, auto, seq.
Index: gcc/c/c-parser.c
===================================================================
--- gcc/c/c-parser.c (revision 228969)
+++ gcc/c/c-parser.c (working copy)
@@ -11185,6 +11185,138 @@ c_parser_omp_clause_num_workers (c_parse
}
/* OpenACC:
+ gang [( gang_expr_list )]
+ worker [( expression )]
+ vector [( expression )] */
+
+static tree
+c_parser_oacc_shape_clause (c_parser *parser, pragma_omp_clause c_kind,
+ const char *str, tree list)
+{
+ omp_clause_code kind;
+ const char *id = "num";
+
+ switch (c_kind)
+ {
+ default:
+ gcc_unreachable ();
+ case PRAGMA_OACC_CLAUSE_GANG:
+ kind = OMP_CLAUSE_GANG;
+ break;
+ case PRAGMA_OACC_CLAUSE_VECTOR:
+ kind = OMP_CLAUSE_VECTOR;
+ id = "length";
+ break;
+ case PRAGMA_OACC_CLAUSE_WORKER:
+ kind = OMP_CLAUSE_WORKER;
+ break;
+ }
+
+ tree op0 = NULL_TREE, op1 = NULL_TREE;
+ location_t loc = c_parser_peek_token (parser)->location;
+
+ if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
+ {
+ tree *op_to_parse = &op0;
+ c_parser_consume_token (parser);
+
+ do
+ {
+ if (c_parser_next_token_is (parser, CPP_NAME)
+ || c_parser_next_token_is (parser, CPP_KEYWORD))
+ {
+ tree name_kind = c_parser_peek_token (parser)->value;
+ const char *p = IDENTIFIER_POINTER (name_kind);
+ if (kind == OMP_CLAUSE_GANG && strcmp ("static", p) == 0)
+ {
+ c_parser_consume_token (parser);
+ if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
+ {
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
+ return list;
+ }
+ op_to_parse = &op1;
+ if (c_parser_next_token_is (parser, CPP_MULT))
+ {
+ c_parser_consume_token (parser);
+ *op_to_parse = integer_minus_one_node;
+ continue;
+ }
+ }
+ else if (strcmp (id, p) == 0)
+ {
+ c_parser_consume_token (parser);
+ if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
+ {
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
+ return list;
+ }
+ }
+ else
+ {
+ if (kind == OMP_CLAUSE_GANG)
+ c_parser_error (parser, "expected %<%num%> or %<static%>");
+ else if (kind == OMP_CLAUSE_VECTOR)
+ c_parser_error (parser, "expected %<length%>");
+ else
+ c_parser_error (parser, "expected %<num%>");
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
+ return list;
+ }
+ }
+
+ if (*op_to_parse != NULL_TREE)
+ {
+ c_parser_error (parser, "duplicate operand to clause");
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
+ return list;
+ }
+
+ tree expr = c_parser_expression (parser).value;
+ if (expr == error_mark_node)
+ {
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
+ return list;
+ }
+
+ mark_exp_read (expr);
+ *op_to_parse = expr;
+ op_to_parse = &op0;
+ }
+ while (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN));
+ c_parser_consume_token (parser);
+ }
+
+ check_no_duplicate_clause (list, kind, str);
+
+ tree c = build_omp_clause (loc, kind);
+ if (op0)
+ OMP_CLAUSE_OPERAND (c, 0) = op0;
+ if (op1)
+ OMP_CLAUSE_OPERAND (c, 1) = op1;
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+}
+
+/* OpenACC:
+ auto
+ independent
+ nohost
+ seq */
+
+static tree
+c_parser_oacc_simple_clause (c_parser *parser ATTRIBUTE_UNUSED,
+ enum omp_clause_code code, tree list)
+{
+ check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
+
+ tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
+ OMP_CLAUSE_CHAIN (c) = list;
+
+ return c;
+}
+
+/* OpenACC:
async [( int-expr )] */
static tree
@@ -12390,6 +12522,11 @@ c_parser_oacc_all_clauses (c_parser *par
clauses = c_parser_oacc_clause_async (parser, clauses);
c_name = "async";
break;
+ case PRAGMA_OACC_CLAUSE_AUTO:
+ clauses = c_parser_oacc_simple_clause (parser, OMP_CLAUSE_AUTO,
+ clauses);
+ c_name = "auto";
+ break;
case PRAGMA_OACC_CLAUSE_COLLAPSE:
clauses = c_parser_omp_clause_collapse (parser, clauses);
c_name = "collapse";
@@ -12426,6 +12563,11 @@ c_parser_oacc_all_clauses (c_parser *par
clauses = c_parser_omp_clause_firstprivate (parser, clauses);
c_name = "firstprivate";
break;
+ case PRAGMA_OACC_CLAUSE_GANG:
+ c_name = "gang";
+ clauses = c_parser_oacc_shape_clause (parser, c_kind, c_name,
+ clauses);
+ break;
case PRAGMA_OACC_CLAUSE_HOST:
clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
c_name = "host";
@@ -12474,6 +12616,16 @@ c_parser_oacc_all_clauses (c_parser *par
clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
c_name = "self";
break;
+ case PRAGMA_OACC_CLAUSE_SEQ:
+ clauses = c_parser_oacc_simple_clause (parser, OMP_CLAUSE_SEQ,
+ clauses);
+ c_name = "seq";
+ break;
+ case PRAGMA_OACC_CLAUSE_VECTOR:
+ c_name = "vector";
+ clauses = c_parser_oacc_shape_clause (parser, c_kind, c_name,
+ clauses);
+ break;
case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
clauses = c_parser_omp_clause_vector_length (parser, clauses);
c_name = "vector_length";
@@ -12482,6 +12634,11 @@ c_parser_oacc_all_clauses (c_parser *par
clauses = c_parser_oacc_clause_wait (parser, clauses);
c_name = "wait";
break;
+ case PRAGMA_OACC_CLAUSE_WORKER:
+ c_name = "worker";
+ clauses = c_parser_oacc_shape_clause (parser, c_kind, c_name,
+ clauses);
+ break;
default:
c_parser_error (parser, "expected %<#pragma acc%> clause");
goto saw_error;
@@ -13012,6 +13169,11 @@ c_parser_oacc_enter_exit_data (c_parser
#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_WORKER) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \
+ | (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