Hi!

This patch adds just the parsing and diagnostics of task reduction modifier.
Such reductions behave then differently, like task_reduction clause on
taskgroup construct when used on parallel or for/sections.

Tested on x86_64-linux, committed to gomp-5_0-branch.

2018-08-01  Jakub Jelinek  <ja...@redhat.com>

        * tree.h (OMP_CLAUSE_REDUCTION_TASK, OMP_CLAUSE_REDUCTION_INSCAN):
        Define.
        * tree-pretty-print.c (dump_omp_clause): Print reduction modifiers.
        * gimplify.c (gimplify_scan_omp_clauses): Handle
        OMP_CLAUSE_REDUCTION_TASK diagnostics.
gcc/c-family/
        * c-omp.c (c_omp_split_clauses): Handle OMP_CLAUSE_REDUCTION_TASK.
gcc/c/
        * c-parser.c (c_parser_omp_clause_reduction): Add IS_OMP argument,
        parse reduction modifiers.
        (c_parser_oacc_all_clauses, c_parser_omp_all_clauses): Adjust
        c_parser_omp_clause_reduction callers.
gcc/cp/
        * parser.c (cp_parser_omp_clause_reduction): Add IS_OMP argument,
        parse reduction modifiers.
        (cp_parser_oacc_all_clauses, cp_parser_omp_all_clauses): Adjust
        cp_parser_omp_clause_reduction callers.
gcc/testsuite/
        * c-c++-common/gomp/reduction-task-1.c: New test.
        * c-c++-common/gomp/reduction-task-2.c: New test.

--- gcc/tree.h.jj       2018-07-17 17:24:39.972318592 +0200
+++ gcc/tree.h  2018-07-30 16:18:35.928699592 +0200
@@ -1614,6 +1614,14 @@ extern tree maybe_wrap_with_location (tr
   (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_REDUCTION, \
                           OMP_CLAUSE_IN_REDUCTION)->base.public_flag)
 
+/* True if a REDUCTION clause has task reduction-modifier.  */
+#define OMP_CLAUSE_REDUCTION_TASK(NODE) \
+  TREE_PROTECTED (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION))
+
+/* True if a REDUCTION clause has inscan reduction-modifier.  */
+#define OMP_CLAUSE_REDUCTION_INSCAN(NODE) \
+  TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION))
+
 /* True if a LINEAR clause doesn't need copy in.  True for iterator vars which
    are always initialized inside of the loop construct, false otherwise.  */
 #define OMP_CLAUSE_LINEAR_NO_COPYIN(NODE) \
--- gcc/tree-pretty-print.c.jj  2018-07-10 11:32:22.271156564 +0200
+++ gcc/tree-pretty-print.c     2018-07-30 18:22:56.159264665 +0200
@@ -477,6 +477,13 @@ dump_omp_clause (pretty_printer *pp, tre
       /* FALLTHRU */
     case OMP_CLAUSE_REDUCTION:
       pp_string (pp, "reduction(");
+      if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_REDUCTION)
+       {
+         if (OMP_CLAUSE_REDUCTION_TASK (clause))
+           pp_string (pp, "task,");
+         else if (OMP_CLAUSE_REDUCTION_INSCAN (clause))
+           pp_string (pp, "inscan,");
+       }
       if (OMP_CLAUSE_REDUCTION_CODE (clause) != ERROR_MARK)
        {
          pp_string (pp,
--- gcc/gimplify.c.jj   2018-07-25 17:40:05.967970906 +0200
+++ gcc/gimplify.c      2018-08-01 14:34:53.945975952 +0200
@@ -7960,6 +7960,7 @@ gimplify_scan_omp_clauses (tree *list_p,
   hash_map<tree, tree> *struct_map_to_clause = NULL;
   tree *prev_list_p = NULL;
   int handled_depend_iterators = -1;
+  int nowait = -1;
 
   ctx = new_omp_context (region_type);
   outer_ctx = ctx->outer_context;
@@ -8113,6 +8114,32 @@ gimplify_scan_omp_clauses (tree *list_p,
            }
          goto do_add;
        case OMP_CLAUSE_REDUCTION:
+         if (OMP_CLAUSE_REDUCTION_TASK (c))
+           {
+             if (region_type == ORT_WORKSHARE)
+               {
+                 if (nowait == -1)
+                   nowait = omp_find_clause (*list_p,
+                                             OMP_CLAUSE_NOWAIT) != NULL_TREE;
+                 if (nowait
+                     && (outer_ctx == NULL
+                         || outer_ctx->region_type != ORT_COMBINED_PARALLEL))
+                   {
+                     error_at (OMP_CLAUSE_LOCATION (c),
+                               "%<task%> reduction modifier on a construct "
+                               "with a %<nowait%> clause");
+                     OMP_CLAUSE_REDUCTION_TASK (c) = 0;
+                   }
+               }
+             else if ((region_type & ORT_PARALLEL) != ORT_PARALLEL)
+               {
+                 error_at (OMP_CLAUSE_LOCATION (c),
+                           "invalid %<task%> reduction modifier on construct "
+                           "other than %<parallel%>, %<for%> or %<sections%>");
+                 OMP_CLAUSE_REDUCTION_TASK (c) = 0;
+               }
+           }
+         /* FALLTHRU */
        case OMP_CLAUSE_IN_REDUCTION:
        case OMP_CLAUSE_TASK_REDUCTION:
          flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
@@ -9016,6 +9043,9 @@ gimplify_scan_omp_clauses (tree *list_p,
          break;
 
        case OMP_CLAUSE_NOWAIT:
+         nowait = 1;
+         break;
+
        case OMP_CLAUSE_ORDERED:
        case OMP_CLAUSE_UNTIED:
        case OMP_CLAUSE_COLLAPSE:
--- gcc/c-family/c-omp.c.jj     2018-07-17 17:24:39.973318593 +0200
+++ gcc/c-family/c-omp.c        2018-08-01 14:04:30.178369000 +0200
@@ -1590,6 +1590,28 @@ c_omp_split_clauses (location_t loc, enu
           Duplicate it on all of them, but omit on for or sections if
           parallel is present.  */
        case OMP_CLAUSE_REDUCTION:
+         if (OMP_CLAUSE_REDUCTION_TASK (clauses))
+           {
+             if (code == OMP_SIMD /* || code == OMP_LOOP */)
+               {
+                 error_at (OMP_CLAUSE_LOCATION (clauses),
+                           "invalid %<task%> reduction modifier on construct "
+                           "combined with %<simd%>" /* or %<loop%> */);
+                 OMP_CLAUSE_REDUCTION_TASK (clauses) = 0;
+               }
+             else if (code != OMP_SECTIONS
+                      && (mask & (OMP_CLAUSE_MASK_1
+                                  << PRAGMA_OMP_CLAUSE_SCHEDULE)) == 0
+                      && (mask & (OMP_CLAUSE_MASK_1
+                                  << PRAGMA_OMP_CLAUSE_SCHEDULE)) == 0)
+               {
+                 error_at (OMP_CLAUSE_LOCATION (clauses),
+                           "invalid %<task%> reduction modifier on construct "
+                           "not combined with %<parallel%>, %<for%> or "
+                           "%<sections%>");
+                 OMP_CLAUSE_REDUCTION_TASK (clauses) = 0;
+               }
+           }
          if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
            {
              if (code == OMP_SIMD)
@@ -1618,9 +1640,9 @@ c_omp_split_clauses (location_t loc, enu
                    = OMP_CLAUSE_REDUCTION_PLACEHOLDER (clauses);
                  OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c)
                    = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (clauses);
-                 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
-                 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] = c;
-                 s = C_OMP_CLAUSE_SPLIT_TEAMS;
+                 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
+                 cclauses[C_OMP_CLAUSE_SPLIT_TEAMS] = c;
+                 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
                }
              else if ((mask & (OMP_CLAUSE_MASK_1
                                << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
--- gcc/c/c-parser.c.jj 2018-07-24 18:19:26.526677938 +0200
+++ gcc/c/c-parser.c    2018-07-31 13:53:31.320112896 +0200
@@ -13076,20 +13076,48 @@ c_parser_omp_clause_private (c_parser *p
      identifier
 
    OpenMP 5.0:
+   reduction ( reduction-modifier, reduction-operator : variable-list )
    in_reduction ( reduction-operator : variable-list )
    task_reduction ( reduction-operator : variable-list )  */
 
 static tree
 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
-                              tree list)
+                              bool is_omp, tree list)
 {
   location_t clause_loc = c_parser_peek_token (parser)->location;
   matching_parens parens;
   if (parens.require_open (parser))
     {
+      bool task = false;
+      bool inscan = false;
       enum tree_code code = ERROR_MARK;
       tree reduc_id = NULL_TREE;
 
+      if (kind == OMP_CLAUSE_REDUCTION && is_omp)
+       {
+         if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
+             && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
+           {
+             c_parser_consume_token (parser);
+             c_parser_consume_token (parser);
+           }
+         else if (c_parser_next_token_is (parser, CPP_NAME)
+                  && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
+           {
+             const char *p
+               = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+             if (strcmp (p, "task") == 0)
+               task = true;
+             else if (strcmp (p, "inscan") == 0)
+               inscan = true;
+             if (task || inscan)
+               {
+                 c_parser_consume_token (parser);
+                 c_parser_consume_token (parser);
+               }
+           }
+       }
+
       switch (c_parser_peek_token (parser)->type)
        {
        case CPP_PLUS:
@@ -13171,6 +13199,10 @@ c_parser_omp_clause_reduction (c_parser
              while (TREE_CODE (type) == ARRAY_TYPE)
                type = TREE_TYPE (type);
              OMP_CLAUSE_REDUCTION_CODE (c) = code;
+             if (task)
+               OMP_CLAUSE_REDUCTION_TASK (c) = 1;
+             else if (inscan)
+               OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
              if (code == ERROR_MARK
                  || !(INTEGRAL_TYPE_P (type)
                       || TREE_CODE (type) == REAL_TYPE
@@ -14452,12 +14484,12 @@ c_parser_oacc_all_clauses (c_parser *par
        case PRAGMA_OACC_CLAUSE_REDUCTION:
          clauses
            = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
-                                            clauses);
+                                            false, clauses);
          c_name = "reduction";
          break;
        case PRAGMA_OACC_CLAUSE_SEQ:
          clauses = c_parser_oacc_simple_clause (parser, OMP_CLAUSE_SEQ,
-                                               clauses);
+                                                clauses);
          c_name = "seq";
          break;
        case PRAGMA_OACC_CLAUSE_TILE:
@@ -14581,7 +14613,7 @@ c_parser_omp_all_clauses (c_parser *pars
        case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
          clauses
            = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
-                                            clauses);
+                                            true, clauses);
          c_name = "in_reduction";
          break;
        case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
@@ -14619,7 +14651,7 @@ c_parser_omp_all_clauses (c_parser *pars
        case PRAGMA_OMP_CLAUSE_REDUCTION:
          clauses
            = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
-                                            clauses);
+                                            true, clauses);
          c_name = "reduction";
          break;
        case PRAGMA_OMP_CLAUSE_SCHEDULE:
@@ -14633,7 +14665,7 @@ c_parser_omp_all_clauses (c_parser *pars
        case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
          clauses
            = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
-                                            clauses);
+                                            true, clauses);
          c_name = "task_reduction";
          break;
        case PRAGMA_OMP_CLAUSE_UNTIED:
--- gcc/cp/parser.c.jj  2018-07-25 11:42:54.123510698 +0200
+++ gcc/cp/parser.c     2018-07-31 13:56:33.842637416 +0200
@@ -32931,19 +32931,47 @@ cp_parser_omp_clause_ordered (cp_parser
      id-expression
 
    OpenMP 5.0:
+   reduction ( reduction-modifier, reduction-operator : variable-list )
    in_reduction ( reduction-operator : variable-list )
    task_reduction ( reduction-operator : variable-list )  */
 
 static tree
 cp_parser_omp_clause_reduction (cp_parser *parser, enum omp_clause_code kind,
-                               tree list)
+                               bool is_omp, tree list)
 {
   enum tree_code code = ERROR_MARK;
   tree nlist, c, id = NULL_TREE;
+  bool task = false;
+  bool inscan = false;
 
   if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
     return list;
 
+  if (kind == OMP_CLAUSE_REDUCTION && is_omp)
+    {
+      if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DEFAULT)
+         && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COMMA))
+       {
+         cp_lexer_consume_token (parser->lexer);
+         cp_lexer_consume_token (parser->lexer);
+       }
+      else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
+              && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COMMA))
+       {
+         tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+         const char *p = IDENTIFIER_POINTER (id);
+         if (strcmp (p, "task") == 0)
+           task = true;
+         else if (strcmp (p, "inscan") == 0)
+           inscan = true;
+         if (task || inscan)
+           {
+             cp_lexer_consume_token (parser->lexer);
+             cp_lexer_consume_token (parser->lexer);
+           }
+       }
+    }
+
   switch (cp_lexer_peek_token (parser->lexer)->type)
     {
     case CPP_PLUS: code = PLUS_EXPR; break;
@@ -33021,6 +33049,10 @@ cp_parser_omp_clause_reduction (cp_parse
   for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
     {
       OMP_CLAUSE_REDUCTION_CODE (c) = code;
+      if (task)
+       OMP_CLAUSE_REDUCTION_TASK (c) = 1;
+      else if (inscan)
+       OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
       OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = id;
     }
 
@@ -34272,7 +34304,7 @@ cp_parser_oacc_all_clauses (cp_parser *p
        case PRAGMA_OACC_CLAUSE_REDUCTION:
          clauses
            = cp_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
-                                             clauses);
+                                             false, clauses);
          c_name = "reduction";
          break;
        case PRAGMA_OACC_CLAUSE_SEQ:
@@ -34422,7 +34454,7 @@ cp_parser_omp_all_clauses (cp_parser *pa
        case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
          clauses
            = cp_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
-                                             clauses);
+                                             true, clauses);
          c_name = "in_reduction";
          break;
        case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
@@ -34466,7 +34498,7 @@ cp_parser_omp_all_clauses (cp_parser *pa
        case PRAGMA_OMP_CLAUSE_REDUCTION:
          clauses
            = cp_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
-                                             clauses);
+                                             true, clauses);
          c_name = "reduction";
          break;
        case PRAGMA_OMP_CLAUSE_SCHEDULE:
@@ -34483,7 +34515,7 @@ cp_parser_omp_all_clauses (cp_parser *pa
          clauses
            = cp_parser_omp_clause_reduction (parser,
                                              OMP_CLAUSE_TASK_REDUCTION,
-                                             clauses);
+                                             true, clauses);
          c_name = "task_reduction";
          break;
        case PRAGMA_OMP_CLAUSE_UNTIED:
--- gcc/testsuite/c-c++-common/gomp/reduction-task-1.c.jj       2018-08-01 
15:14:14.318166966 +0200
+++ gcc/testsuite/c-c++-common/gomp/reduction-task-1.c  2018-07-31 
16:06:16.951634432 +0200
@@ -0,0 +1,86 @@
+int v;
+extern void foo (int);
+
+void
+bar (void)
+{
+  int i;
+  #pragma omp for reduction (task, +: v)
+  for (i = 0; i < 64; i++)
+    foo (i);
+  #pragma omp sections reduction (task, +: v)
+  {
+    foo (-2);
+    #pragma omp section
+    foo (-3);
+  }
+  #pragma omp parallel reduction (task, +: v)
+  foo (-1);
+  #pragma omp parallel for reduction (task, +: v)
+  for (i = 0; i < 64; i++)
+    foo (i);
+  #pragma omp parallel sections reduction (task, +: v)
+  {
+    foo (-2);
+    #pragma omp section
+    foo (-3);
+  }
+  #pragma omp teams distribute parallel for reduction (task, +: v)
+  for (i = 0; i < 64; i++)
+    foo (i);
+  #pragma omp for reduction (default, +: v)
+  for (i = 0; i < 64; i++)
+    foo (i);
+  #pragma omp sections reduction (default, +: v)
+  {
+    foo (-2);
+    #pragma omp section
+    foo (-3);
+  }
+  #pragma omp parallel reduction (default, +: v)
+  foo (-1);
+  #pragma omp parallel for reduction (default, +: v)
+  for (i = 0; i < 64; i++)
+    foo (i);
+  #pragma omp parallel sections reduction (default, +: v)
+  {
+    foo (-2);
+    #pragma omp section
+    foo (-3);
+  }
+  #pragma omp teams distribute parallel for reduction (default, +: v)
+  for (i = 0; i < 64; i++)
+    foo (i);
+  #pragma omp for reduction (default, +: v) nowait
+  for (i = 0; i < 64; i++)
+    foo (i);
+  #pragma omp sections nowait reduction (default, +: v)
+  {
+    foo (-2);
+    #pragma omp section
+    foo (-3);
+  }
+  #pragma omp simd reduction (default, +: v)
+  for (i = 0; i < 64; i++)
+    v++;
+  #pragma omp for simd reduction (default, +: v)
+  for (i = 0; i < 64; i++)
+    v++;
+  #pragma omp parallel for simd reduction (default, +: v)
+  for (i = 0; i < 64; i++)
+    v++;
+  #pragma omp teams distribute parallel for simd reduction (default, +: v)
+  for (i = 0; i < 64; i++)
+    v++;
+  #pragma omp taskloop reduction (default, +: v)
+  for (i = 0; i < 64; i++)
+    foo (i);
+  #pragma omp taskloop simd reduction (default, +: v)
+  for (i = 0; i < 64; i++)
+    v++;
+  #pragma omp teams reduction (default, +: v)
+  foo (i);
+  #pragma omp teams distribute reduction (default, +: v)
+  for (i = 0; i < 64; i++)
+    foo (i);
+}
--- gcc/testsuite/c-c++-common/gomp/reduction-task-2.c.jj       2018-08-01 
15:14:18.040177038 +0200
+++ gcc/testsuite/c-c++-common/gomp/reduction-task-2.c  2018-08-01 
14:27:51.320913239 +0200
@@ -0,0 +1,40 @@
+int v;
+extern void foo (int);
+
+void
+bar (void)
+{
+  int i;
+  #pragma omp for reduction (task, +: v) nowait        /* { dg-error "'task' 
reduction modifier on a construct with a 'nowait' clause" } */
+  for (i = 0; i < 64; i++)
+    foo (i);
+  #pragma omp sections nowait reduction (task, +: v)   /* { dg-error "'task' 
reduction modifier on a construct with a 'nowait' clause" } */
+  {
+    foo (-2);
+    #pragma omp section
+    foo (-3);
+  }
+  #pragma omp simd reduction (task, +: v)      /* { dg-error "invalid 'task' 
reduction modifier on construct other than 'parallel', 'for' or 'sections'" } */
+  for (i = 0; i < 64; i++)
+    v++;
+  #pragma omp for simd reduction (task, +: v)  /* { dg-error "invalid 'task' 
reduction modifier on construct combined with 'simd'" } */
+  for (i = 0; i < 64; i++)
+    v++;
+  #pragma omp parallel for simd reduction (task, +: v) /* { dg-error "invalid 
'task' reduction modifier on construct combined with 'simd'" } */
+  for (i = 0; i < 64; i++)
+    v++;
+  #pragma omp teams distribute parallel for simd reduction (task, +: v)        
/* { dg-error "invalid 'task' reduction modifier on construct combined with 
'simd'" } */
+  for (i = 0; i < 64; i++)
+    v++;
+  #pragma omp taskloop reduction (task, +: v)  /* { dg-error "invalid 'task' 
reduction modifier on construct other than 'parallel', 'for' or 'sections'" } */
+  for (i = 0; i < 64; i++)
+    foo (i);
+  #pragma omp taskloop simd reduction (task, +: v)     /* { dg-error "invalid 
'task' reduction modifier on construct combined with 'simd'" } */
+  for (i = 0; i < 64; i++)
+    v++;
+  #pragma omp teams reduction (task, +: v)     /* { dg-error "invalid 'task' 
reduction modifier on construct other than 'parallel', 'for' or 'sections'" } */
+  foo (i);
+  #pragma omp teams distribute reduction (task, +: v)  /* { dg-error "invalid 
'task' reduction modifier on construct not combined with 'parallel', 'for' or 
'sections'" } */
+  for (i = 0; i < 64; i++)
+    foo (i);
+}

        Jakub

Reply via email to