This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gomp4.1] Parse linear clause modifiers


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]