diff mbox

[gomp5] Add C/C++ lastprivate(conditional: ...) parsing

Message ID 20170510134646.GW1809@tucnak
State New
Headers show

Commit Message

Jakub Jelinek May 10, 2017, 1:46 p.m. UTC
Hi!

This patch adds so far just parsing and diagnostics of conditional:
modifier to lastprivate clause.
Implementation for simd will require some vectorizer improvements,
for non-orphaned worksharing I think I can add a shared variable on the
parallel holding max so far stored iteration # and reduce based on that,
orphaned worksharing will be require some library work too.

2017-05-10  Jakub Jelinek  <jakub@redhat.com>

	* tree.h (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL): Define.
	* tree-pretty-print.c (dump_omp_clause) <case OMP_CLAUSE_LASTPRIVATE>:
	Print conditional: for OMP_CLAUSE_LASTPRIVATE_CONDITIONAL.
	* gimplify.c (gimplify_scan_omp_clauses): Diagnose invalid
	gimplify_scan_omp_clauses.
c-family/
	* c-omp.c (c_omp_split_clauses): Copy
	OMP_CLAUSE_LASTPRIVATE_CONDITIONAL.
c/
	* c-parser.c (c_parser_omp_clause_lastprivate): Parse optional
	conditional: modifier.
	(c_parser_cilk_all_clauses): Call c_parser_omp_var_list_parens
	directly.
cp/
	* parser.c (cp_parser_omp_clause_lastprivate): New function.
	(cp_parser_omp_all_clauses): Call it for OpenMP lastprivate clause.


	Jakub
diff mbox

Patch

--- gcc/tree.h.jj	2017-05-04 15:05:06.000000000 +0200
+++ gcc/tree.h	2017-05-09 16:42:05.460935117 +0200
@@ -1469,6 +1469,10 @@  extern void protected_set_expr_location
 #define OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV(NODE) \
   TREE_PROTECTED (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LASTPRIVATE))
 
+/* True if a LASTPRIVATE clause has CONDITIONAL: modifier.  */
+#define OMP_CLAUSE_LASTPRIVATE_CONDITIONAL(NODE) \
+  TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LASTPRIVATE))
+
 /* True on a SHARED clause if a FIRSTPRIVATE clause for the same
    decl is present in the chain (this can happen only for taskloop
    with FIRSTPRIVATE/LASTPRIVATE on it originally.  */
--- gcc/tree-pretty-print.c.jj	2017-05-04 15:05:05.000000000 +0200
+++ gcc/tree-pretty-print.c	2017-05-09 16:45:46.542093806 +0200
@@ -389,7 +389,13 @@  dump_omp_clause (pretty_printer *pp, tre
       goto print_remap;
     case OMP_CLAUSE_LASTPRIVATE:
       name = "lastprivate";
-      goto print_remap;
+      if (!OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (clause))
+	goto print_remap;
+      pp_string (pp, "lastprivate(conditional:");
+      dump_generic_node (pp, OMP_CLAUSE_DECL (clause),
+			 spc, flags, false);
+      pp_right_paren (pp);
+      break;
     case OMP_CLAUSE_COPYIN:
       name = "copyin";
       goto print_remap;
--- gcc/gimplify.c.jj	2017-05-04 15:05:58.000000000 +0200
+++ gcc/gimplify.c	2017-05-10 12:58:56.400849056 +0200
@@ -7431,16 +7431,42 @@  gimplify_scan_omp_clauses (tree *list_p,
 	  check_non_private = "firstprivate";
 	  goto do_add;
 	case OMP_CLAUSE_LASTPRIVATE:
+	  if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
+	    switch (code)
+	      {
+	      case OMP_DISTRIBUTE:
+		error_at (OMP_CLAUSE_LOCATION (c),
+			  "conditional %<lastprivate%> clause on "
+			  "%<distribute%> construct");
+		OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
+		break;
+	      case OMP_TASKLOOP:
+		error_at (OMP_CLAUSE_LOCATION (c),
+			  "conditional %<lastprivate%> clause on "
+			  "%<taskloop%> construct");
+		OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
+		break;
+	      default:
+		break;
+	      }
 	  flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
 	  check_non_private = "lastprivate";
 	  decl = OMP_CLAUSE_DECL (c);
 	  if (error_operand_p (decl))
 	    goto do_add;
-	  else if (outer_ctx
-		   && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
-		       || outer_ctx->region_type == ORT_COMBINED_TEAMS)
-		   && splay_tree_lookup (outer_ctx->variables,
-					 (splay_tree_key) decl) == NULL)
+	  if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
+	      && !lang_hooks.decls.omp_scalar_p (decl))
+	    {
+	      error_at (OMP_CLAUSE_LOCATION (c),
+			"non-scalar variable %qD in conditional "
+			"%<lastprivate%> clause", decl);
+	      OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
+	    }
+	  if (outer_ctx
+	      && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
+		  || outer_ctx->region_type == ORT_COMBINED_TEAMS)
+	      && splay_tree_lookup (outer_ctx->variables,
+				    (splay_tree_key) decl) == NULL)
 	    {
 	      omp_add_variable (outer_ctx, decl, GOVD_SHARED | GOVD_SEEN);
 	      if (outer_ctx->outer_context)
--- gcc/c-family/c-omp.c.jj	2017-05-04 15:05:05.000000000 +0200
+++ gcc/c-family/c-omp.c	2017-05-09 17:39:18.503872276 +0200
@@ -1191,6 +1191,8 @@  c_omp_split_clauses (location_t loc, enu
 				    OMP_CLAUSE_LASTPRIVATE);
 	      OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
 	      OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
+	      OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
+		= OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (clauses);
 	      cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE] = c;
 	    }
 	  if (code == OMP_FOR || code == OMP_SECTIONS)
@@ -1208,6 +1210,8 @@  c_omp_split_clauses (location_t loc, enu
 	      c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
 				    OMP_CLAUSE_LASTPRIVATE);
 	      OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
+	      OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
+		= OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (clauses);
 	      if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
 		  != 0)
 		s = C_OMP_CLAUSE_SPLIT_PARALLEL;
--- gcc/c/c-parser.c.jj	2017-05-09 14:05:46.000000000 +0200
+++ gcc/c/c-parser.c	2017-05-09 17:39:01.422091178 +0200
@@ -11401,12 +11401,41 @@  c_parser_omp_clause_if (c_parser *parser
 }
 
 /* OpenMP 2.5:
-   lastprivate ( variable-list ) */
+   lastprivate ( variable-list )
+
+   OpenMP 5.0:
+   lastprivate ( [ lastprivate-modifier : ] variable-list ) */
 
 static tree
 c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
 {
-  return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LASTPRIVATE, list);
+  /* The clauses location.  */
+  location_t loc = c_parser_peek_token (parser)->location;
+
+  if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+    {
+      bool conditional = false;
+      if (c_parser_next_token_is (parser, CPP_NAME)
+	  && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
+	{
+	  const char *p
+	    = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+	  if (strcmp (p, "conditional") == 0)
+	    {
+	      conditional = true;
+	      c_parser_consume_token (parser);
+	      c_parser_consume_token (parser);
+	    }
+	}
+      tree nlist = c_parser_omp_variable_list (parser, loc,
+					       OMP_CLAUSE_LASTPRIVATE, list);
+      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+      if (conditional)
+	for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
+	  OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
+      return nlist;
+    }
+  return list;
 }
 
 /* OpenMP 3.1:
@@ -17872,8 +17901,9 @@  c_parser_cilk_all_clauses (c_parser *par
 	  clauses = c_parser_omp_clause_firstprivate (parser, clauses);
 	  break;
 	case PRAGMA_CILK_CLAUSE_LASTPRIVATE:
-	  /* Use the OpenMP counterpart.  */
-	  clauses = c_parser_omp_clause_lastprivate (parser, clauses);
+	  clauses
+	    = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LASTPRIVATE,
+					    clauses);
 	  break;
 	case PRAGMA_CILK_CLAUSE_REDUCTION:
 	  /* Use the OpenMP counterpart.  */
--- gcc/cp/parser.c.jj	2017-05-09 09:53:42.000000000 +0200
+++ gcc/cp/parser.c	2017-05-09 17:23:49.610793472 +0200
@@ -32459,6 +32459,43 @@  cp_parser_omp_clause_aligned (cp_parser
   return nlist;
 }
 
+/* OpenMP 2.5:
+   lastprivate ( variable-list )
+
+   OpenMP 5.0:
+   lastprivate ( [ lastprivate-modifier : ] variable-list )  */
+
+static tree
+cp_parser_omp_clause_lastprivate (cp_parser *parser, tree list, location_t loc)
+{
+  bool conditional = false;
+
+  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+    return list;
+
+  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
+      && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON))
+    {
+      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+      const char *p = IDENTIFIER_POINTER (id);
+
+      if (strcmp ("conditional", p) == 0)
+	{
+	  conditional = true;
+	  cp_lexer_consume_token (parser->lexer);
+	  cp_lexer_consume_token (parser->lexer);
+	}
+    }
+
+  tree nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_LASTPRIVATE,
+					       list, NULL);
+
+  if (conditional)
+    for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
+      OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
+  return nlist;
+}
+
 /* OpenMP 4.0:
    linear ( variable-list )
    linear ( variable-list : expression )
@@ -33334,8 +33371,8 @@  cp_parser_omp_all_clauses (cp_parser *pa
 	  c_name = "if";
 	  break;
 	case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
-	  clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_LASTPRIVATE,
-					    clauses);
+	  clauses = cp_parser_omp_clause_lastprivate (parser, clauses,
+						      token->location);
 	  c_name = "lastprivate";
 	  break;
 	case PRAGMA_OMP_CLAUSE_MERGEABLE: