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  <ja...@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.

--- 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:

        Jakub

Reply via email to