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]

Re: [OpenACC 4/11] C FE changes


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  <cesar@codesourcery.com>
	    Thomas Schwinge  <thomas@codesourcery.com>
	    James Norris  <jnorris@codesourcery.com>
	    Joseph Myers  <joseph@codesourcery.com>
	    Julian Brown  <julian@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

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