This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[gomp4.1] Parse linear clause modifiers
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 11 Jun 2015 17:26:47 +0200
- Subject: [gomp4.1] Parse linear clause modifiers
- Authentication-results: sourceware.org; auth=none
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
OpenMP 4.1 allows modifiers on the linear clause, like:
#ifdef __cplusplus
#pragma omp declare simd linear(ref(a):1) linear(val(b)) linear(uval(c))
int foo (int &a, int &b, int &c);
#else
#pragma omp declare simd linear(a:1) linear(val(b)) linear(uval(c))
int bar (int a, int b, int c);
#endif
This patch parses them and checks requirements. Further changes
(for elemental function handling and vectorization) will depend on the
vector ABI details.
2015-06-11 Jakub Jelinek <jakub@redhat.com>
* tree-core.h (enum omp_clause_linear_kind): New.
(struct tree_omp_clause): Add subcode.linear_kind.
* tree.h (OMP_CLAUSE_LINEAR_KIND): Define.
* tree-pretty-print.h (dump_omp_clause): Dump linear
clause modifiers.
c/
* c-parser.c (c_parser_omp_clause_linear): Handle linear clause
modifiers.
cp/
* parser.c (cp_parser_omp_clause_linear): Handle linear clause
modifiers.
* semantics.c (finish_omp_clauses): Diagnose linear(ref(var))
where var isn't a reference. Don't use pointer_sum
for ref(var), just multiply by size of pointer.
--- gcc/tree-core.h.jj 2015-06-08 11:08:41.000000000 +0200
+++ gcc/tree-core.h 2015-06-11 14:34:43.926623065 +0200
@@ -1264,6 +1264,14 @@ enum omp_clause_proc_bind_kind
OMP_CLAUSE_PROC_BIND_LAST
};
+enum omp_clause_linear_kind
+{
+ OMP_CLAUSE_LINEAR_DEFAULT,
+ OMP_CLAUSE_LINEAR_REF,
+ OMP_CLAUSE_LINEAR_VAL,
+ OMP_CLAUSE_LINEAR_UVAL
+};
+
struct GTY(()) tree_exp {
struct tree_typed typed;
location_t locus;
@@ -1328,6 +1336,7 @@ struct GTY(()) tree_omp_clause {
unsigned char map_kind;
enum omp_clause_proc_bind_kind proc_bind_kind;
enum tree_code reduction_code;
+ enum omp_clause_linear_kind linear_kind;
} GTY ((skip)) subcode;
/* The gimplification of OMP_CLAUSE_REDUCTION_{INIT,MERGE} for omp-low's
--- gcc/tree.h.jj 2015-06-08 10:48:20.000000000 +0200
+++ gcc/tree.h 2015-06-11 14:36:37.236879987 +0200
@@ -1494,6 +1494,9 @@ extern void protected_set_expr_location
#define OMP_CLAUSE_LINEAR_GIMPLE_SEQ(NODE) \
(OMP_CLAUSE_CHECK (NODE))->omp_clause.gimple_reduction_init
+#define OMP_CLAUSE_LINEAR_KIND(NODE) \
+ (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LINEAR)->omp_clause.subcode.linear_kind)
+
#define OMP_CLAUSE_ALIGNED_ALIGNMENT(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_ALIGNED), 1)
--- gcc/tree-pretty-print.c.jj 2015-06-11 11:32:39.000000000 +0200
+++ gcc/tree-pretty-print.c 2015-06-11 14:43:37.367415531 +0200
@@ -495,8 +495,26 @@ dump_omp_clause (pretty_printer *pp, tre
case OMP_CLAUSE_LINEAR:
pp_string (pp, "linear(");
+ switch (OMP_CLAUSE_LINEAR_KIND (clause))
+ {
+ case OMP_CLAUSE_LINEAR_DEFAULT:
+ break;
+ case OMP_CLAUSE_LINEAR_REF:
+ pp_string (pp, "ref(");
+ break;
+ case OMP_CLAUSE_LINEAR_VAL:
+ pp_string (pp, "val(");
+ break;
+ case OMP_CLAUSE_LINEAR_UVAL:
+ pp_string (pp, "uval(");
+ break;
+ default:
+ gcc_unreachable ();
+ }
dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
spc, flags, false);
+ if (OMP_CLAUSE_LINEAR_KIND (clause) != OMP_CLAUSE_LINEAR_DEFAULT)
+ pp_right_paren (pp);
pp_colon (pp);
dump_generic_node (pp, OMP_CLAUSE_LINEAR_STEP (clause),
spc, flags, false);
--- gcc/c/c-parser.c.jj 2015-06-11 13:02:30.000000000 +0200
+++ gcc/c/c-parser.c 2015-06-11 17:00:21.046632435 +0200
@@ -11461,20 +11461,46 @@ c_parser_omp_clause_aligned (c_parser *p
/* OpenMP 4.0:
linear ( variable-list )
- linear ( variable-list : expression ) */
+ linear ( variable-list : expression )
+
+ OpenMP 4.1:
+ linear ( modifier ( variable-list ) )
+ linear ( modifier ( variable-list ) : expression ) */
static tree
c_parser_omp_clause_linear (c_parser *parser, tree list, bool is_cilk_simd_fn)
{
location_t clause_loc = c_parser_peek_token (parser)->location;
tree nl, c, step;
+ enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
return list;
+ if (!is_cilk_simd_fn
+ && 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)
+ kind = OMP_CLAUSE_LINEAR_VAL;
+ else if (strcmp ("uval", p) == 0)
+ kind = OMP_CLAUSE_LINEAR_UVAL;
+ if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
+ kind = OMP_CLAUSE_LINEAR_DEFAULT;
+ if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
+ {
+ c_parser_consume_token (parser);
+ c_parser_consume_token (parser);
+ }
+ }
+
nl = c_parser_omp_variable_list (parser, clause_loc,
OMP_CLAUSE_LINEAR, list);
+ if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+
if (c_parser_next_token_is (parser, CPP_COLON))
{
c_parser_consume_token (parser);
@@ -11500,6 +11526,7 @@ c_parser_omp_clause_linear (c_parser *pa
for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
{
OMP_CLAUSE_LINEAR_STEP (c) = step;
+ OMP_CLAUSE_LINEAR_KIND (c) = kind;
}
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
--- gcc/cp/parser.c.jj 2015-06-11 13:03:19.000000000 +0200
+++ gcc/cp/parser.c 2015-06-11 16:59:24.879484663 +0200
@@ -28965,7 +28965,11 @@ cp_parser_omp_clause_aligned (cp_parser
/* OpenMP 4.0:
linear ( variable-list )
- linear ( variable-list : expression ) */
+ linear ( variable-list : expression )
+
+ OpenMP 4.1:
+ linear ( modifier ( variable-list ) )
+ linear ( modifier ( variable-list ) : expression ) */
static tree
cp_parser_omp_clause_linear (cp_parser *parser, tree list,
@@ -28973,12 +28977,43 @@ cp_parser_omp_clause_linear (cp_parser *
{
tree nlist, c, step = integer_one_node;
bool colon;
+ enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
return list;
- nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_LINEAR, list,
- &colon);
+ if (!is_cilk_simd_fn
+ && cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+
+ if (strcmp ("ref", p) == 0)
+ kind = OMP_CLAUSE_LINEAR_REF;
+ else if (strcmp ("val", p) == 0)
+ kind = OMP_CLAUSE_LINEAR_VAL;
+ else if (strcmp ("uval", p) == 0)
+ kind = OMP_CLAUSE_LINEAR_UVAL;
+ if (cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN))
+ cp_lexer_consume_token (parser->lexer);
+ else
+ kind = OMP_CLAUSE_LINEAR_DEFAULT;
+ }
+
+ if (kind == OMP_CLAUSE_LINEAR_DEFAULT)
+ nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_LINEAR, list,
+ &colon);
+ else
+ {
+ nlist = cp_parser_omp_var_list (parser, OMP_CLAUSE_LINEAR, list);
+ colon = cp_lexer_next_token_is (parser->lexer, CPP_COLON);
+ if (colon)
+ cp_parser_require (parser, CPP_COLON, RT_COLON);
+ else if (!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);
+ }
if (colon)
{
@@ -28999,7 +29034,10 @@ cp_parser_omp_clause_linear (cp_parser *
}
for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
- OMP_CLAUSE_LINEAR_STEP (c) = step;
+ {
+ OMP_CLAUSE_LINEAR_STEP (c) = step;
+ OMP_CLAUSE_LINEAR_KIND (c) = kind;
+ }
return nlist;
}
--- gcc/cp/semantics.c.jj 2015-06-10 16:09:56.000000000 +0200
+++ gcc/cp/semantics.c 2015-06-11 17:12:29.324582468 +0200
@@ -5579,6 +5579,15 @@ finish_omp_clauses (tree clauses, bool a
if (!type_dependent_expression_p (t))
{
tree type = TREE_TYPE (t);
+ if (OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_REF
+ && TREE_CODE (type) != REFERENCE_TYPE)
+ {
+ error ("linear clause with %<ref%> modifier applied to "
+ "non-reference variable with %qT type",
+ TREE_TYPE (t));
+ remove = true;
+ break;
+ }
if (TREE_CODE (type) == REFERENCE_TYPE)
type = TREE_TYPE (type);
if (!INTEGRAL_TYPE_P (type)
@@ -5616,7 +5625,16 @@ finish_omp_clauses (tree clauses, bool a
tree type = TREE_TYPE (OMP_CLAUSE_DECL (c));
if (TREE_CODE (type) == REFERENCE_TYPE)
type = TREE_TYPE (type);
- if (TREE_CODE (type) == POINTER_TYPE)
+ if (OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_REF)
+ {
+ type = TREE_TYPE (OMP_CLAUSE_DECL (c));
+ t = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
+ sizetype, t);
+ t = fold_build2_loc (OMP_CLAUSE_LOCATION (c),
+ MULT_EXPR, sizetype, t,
+ TYPE_SIZE_UNIT (type));
+ }
+ else if (TREE_CODE (type) == POINTER_TYPE)
{
tree d = convert_from_reference (OMP_CLAUSE_DECL (c));
t = pointer_int_sum (OMP_CLAUSE_LOCATION (c), PLUS_EXPR,
Jakub