]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gimplify.c (enum omp_region_type): Add ORT_TASKLOOP and ORT_UNTIED_TASKLOOP.
authorJakub Jelinek <jakub@redhat.com>
Thu, 18 Oct 2018 16:11:12 +0000 (18:11 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 18 Oct 2018 16:11:12 +0000 (18:11 +0200)
* gimplify.c (enum omp_region_type): Add ORT_TASKLOOP and
ORT_UNTIED_TASKLOOP.
(omp_default_clause): Print "taskloop" rather than "task" if
ORT_*TASKLOOP.
(gimplify_scan_omp_clauses): Add shared clause on parallel for
combined parallel master taskloop{, simd} if taskloop has
firstprivate, lastprivate or reduction clause.
(gimplify_omp_for): Likewise.  Use ORT_TASKLOOP or
ORT_UNTIED_TASKLOOP instead of ORT_TASK or ORT_UNTIED_TASK.
gcc/c-family/
* c-omp.c (c_omp_split_clauses): Add support for combined
#pragma omp parallel master and
#pragma omp {,parallel }master taskloop{, simd} constructs.
gcc/c/
* c-parser.c (c_parser_omp_taskloop): Add forward declaration.
Disallow in_reduction clause when combined with parallel master.
(c_parser_omp_master): Add p_name, mask and cclauses arguments.
Allow to be called while parsing combined parallel master.
Parse combined master taskloop{, simd}.
(c_parser_omp_parallel): Parse combined
parallel master{, taskloop{, simd}} constructs.
(c_parser_omp_construct) <case PRAGMA_OMP_MASTER>: Adjust
c_parser_omp_master caller.
gcc/cp/
* parser.c (cp_parser_omp_taskloop): Add forward declaration.
Disallow in_reduction clause when combined with parallel master.
(cp_parser_omp_master): Add p_name, mask and cclauses arguments.
Allow to be called while parsing combined parallel master.
Parse combined master taskloop{, simd}.
(cp_parser_omp_parallel): Parse combined
parallel master{, taskloop{, simd}} constructs.
(cp_parser_omp_construct) <case PRAGMA_OMP_MASTER>: Adjust
c_parser_omp_master caller.
gcc/testsuite/
* c-c++-common/gomp/clauses-1.c (foo): Add ntm argument and
test if and nontemporal clauses on constructs with simd.
(bar): Add ntm and i3 arguments.  Test if and nontemporal clauses
on constructs with simd.  Change if clauses on some constructs from
specific to the particular constituents to one without a modifier.
Add new tests for combined host teams and for new parallel master
and {,parallel }master taskloop{, simd} combined constructs.
(baz): New function with host teams tests.
* c-c++-common/gomp/default-1.c: New test.
* c-c++-common/gomp/master-combined-1.c: New test.
* c-c++-common/gomp/master-combined-2.c: New test.
libgomp/
* testsuite/libgomp.c-c++-common/master-combined-1.c: New test.
* testsuite/libgomp.c-c++-common/taskloop-reduction-3.c: New test.
* testsuite/libgomp.c-c++-common/taskloop-reduction-4.c: New test.

From-SVN: r265273

17 files changed:
gcc/ChangeLog.gomp
gcc/c-family/ChangeLog.gomp
gcc/c-family/c-omp.c
gcc/c/ChangeLog.gomp
gcc/c/c-parser.c
gcc/cp/ChangeLog.gomp
gcc/cp/parser.c
gcc/gimplify.c
gcc/testsuite/ChangeLog.gomp
gcc/testsuite/c-c++-common/gomp/clauses-1.c
gcc/testsuite/c-c++-common/gomp/default-1.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/gomp/master-combined-1.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/gomp/master-combined-2.c [new file with mode: 0644]
libgomp/ChangeLog.gomp
libgomp/testsuite/libgomp.c-c++-common/master-combined-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-3.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-4.c [new file with mode: 0644]

index 9177582ce2903a28163cf7a477a636703b9db445..3743c42cac96e68b4306a9e19b077856c75e2503 100644 (file)
@@ -1,3 +1,15 @@
+2018-10-18  Jakub Jelinek  <jakub@redhat.com>
+
+       * gimplify.c (enum omp_region_type): Add ORT_TASKLOOP and
+       ORT_UNTIED_TASKLOOP.
+       (omp_default_clause): Print "taskloop" rather than "task" if
+       ORT_*TASKLOOP.
+       (gimplify_scan_omp_clauses): Add shared clause on parallel for
+       combined parallel master taskloop{, simd} if taskloop has
+       firstprivate, lastprivate or reduction clause.
+       (gimplify_omp_for): Likewise.  Use ORT_TASKLOOP or
+       ORT_UNTIED_TASKLOOP instead of ORT_TASK or ORT_UNTIED_TASK.
+
 2018-10-16  Jakub Jelinek  <jakub@redhat.com>
 
        * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE__REDUCTEMP_.
index a4b9be14c103b8f64afd76aab4195421ddc2a8a6..9d763eefdc6bd9322a9f5b93b633a1ce4d943dc9 100644 (file)
@@ -1,3 +1,9 @@
+2018-10-18  Jakub Jelinek  <jakub@redhat.com>
+
+       * c-omp.c (c_omp_split_clauses): Add support for combined
+       #pragma omp parallel master and
+       #pragma omp {,parallel }master taskloop{, simd} constructs.
+
 2018-10-16  Jakub Jelinek  <jakub@redhat.com>
 
        * c-omp.c (c_omp_split_clauses) <case OMP_CLAUSE_IN_REDUCTION>: For
index 630d41b73156c0ea2202d9f322fe480d88605eb1..c7d44560da5081b6fc819f15fb724218bd3b6398 100644 (file)
@@ -1260,18 +1260,24 @@ c_oacc_split_loop_clauses (tree clauses, tree *not_loop_clauses,
 }
 
 /* This function attempts to split or duplicate clauses for OpenMP
-   combined/composite constructs.  Right now there are 21 different
+   combined/composite constructs.  Right now there are 26 different
    constructs.  CODE is the innermost construct in the combined construct,
    and MASK allows to determine which constructs are combined together,
    as every construct has at least one clause that no other construct
-   has (except for OMP_SECTIONS, but that can be only combined with parallel).
+   has (except for OMP_SECTIONS, but that can be only combined with parallel,
+   and OMP_MASTER, which doesn't have any clauses at all).
    OpenMP combined/composite constructs are:
    #pragma omp distribute parallel for
    #pragma omp distribute parallel for simd
    #pragma omp distribute simd
    #pragma omp for simd
+   #pragma omp master taskloop
+   #pragma omp master taskloop simd
    #pragma omp parallel for
    #pragma omp parallel for simd
+   #pragma omp parallel master
+   #pragma omp parallel master taskloop
+   #pragma omp parallel master taskloop simd
    #pragma omp parallel sections
    #pragma omp target parallel
    #pragma omp target parallel for
@@ -1305,8 +1311,9 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
       {
       case OMP_FOR:
       case OMP_SIMD:
-        cclauses[C_OMP_CLAUSE_SPLIT_FOR]
-         = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
+       if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
+         cclauses[C_OMP_CLAUSE_SPLIT_FOR]
+           = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
        break;
       case OMP_SECTIONS:
        cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS]
@@ -1411,8 +1418,8 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
          else
            s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
          break;
-       /* Private clause is supported on all constructs,
-          it is enough to put it on the innermost one.  For
+       /* Private clause is supported on all constructs but master,
+          it is enough to put it on the innermost one other than master.  For
           #pragma omp {for,sections} put it on parallel though,
           as that's what we did for OpenMP 3.1.  */
        case OMP_CLAUSE_PRIVATE:
@@ -1423,12 +1430,14 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
            case OMP_PARALLEL: s = C_OMP_CLAUSE_SPLIT_PARALLEL; break;
            case OMP_DISTRIBUTE: s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE; break;
            case OMP_TEAMS: s = C_OMP_CLAUSE_SPLIT_TEAMS; break;
+           case OMP_MASTER: s = C_OMP_CLAUSE_SPLIT_PARALLEL; break;
+           case OMP_TASKLOOP: s = C_OMP_CLAUSE_SPLIT_TASKLOOP; break;
            default: gcc_unreachable ();
            }
          break;
        /* Firstprivate clause is supported on all constructs but
-          simd.  Put it on the outermost of those and duplicate on teams
-          and parallel.  */
+          simd and master.  Put it on the outermost of those and duplicate on
+          teams and parallel.  */
        case OMP_CLAUSE_FIRSTPRIVATE:
          if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP))
              != 0)
@@ -1467,6 +1476,11 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
                  else
                    s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
                }
+             else if ((mask & (OMP_CLAUSE_MASK_1
+                               << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0)
+               /* This must be
+                  #pragma omp parallel master taskloop{, simd}.  */
+               s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
              else
                /* This must be
                   #pragma omp parallel{, for{, simd}, sections}
@@ -1496,8 +1510,10 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
          else if ((mask & (OMP_CLAUSE_MASK_1
                            << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0)
            {
-             /* This must be #pragma omp taskloop simd.  */
-             gcc_assert (code == OMP_SIMD);
+             /* This must be #pragma omp {,{,parallel }master }taskloop simd
+                or
+                #pragma omp {,parallel }master taskloop.  */
+             gcc_assert (code == OMP_SIMD || code == OMP_TASKLOOP);
              s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
            }
          else
@@ -1507,9 +1523,9 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
              s = C_OMP_CLAUSE_SPLIT_FOR;
            }
          break;
-       /* Lastprivate is allowed on distribute, for, sections and simd.  In
-          parallel {for{, simd},sections} we actually want to put it on
-          parallel rather than for or sections.  */
+       /* Lastprivate is allowed on distribute, for, sections, taskloop and
+          simd.  In parallel {for{, simd},sections} we actually want to put
+          it on parallel rather than for or sections.  */
        case OMP_CLAUSE_LASTPRIVATE:
          if (code == OMP_DISTRIBUTE)
            {
@@ -1536,6 +1552,11 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
                s = C_OMP_CLAUSE_SPLIT_FOR;
              break;
            }
+         if (code == OMP_TASKLOOP)
+           {
+             s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
+             break;
+           }
          gcc_assert (code == OMP_SIMD);
          if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
            {
@@ -1552,6 +1573,16 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
              OMP_CLAUSE_CHAIN (c) = cclauses[s];
              cclauses[s] = c;
            }
+         if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0)
+           {
+             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);
+             OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
+             cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP] = c;
+           }
          s = C_OMP_CLAUSE_SPLIT_SIMD;
          break;
        /* Shared and default clauses are allowed on parallel, teams and
@@ -1561,6 +1592,19 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
          if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
              != 0)
            {
+             if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
+                 != 0)
+               {
+                 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
+                                       OMP_CLAUSE_CODE (clauses));
+                 if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_SHARED)
+                   OMP_CLAUSE_DECL (c) = OMP_CLAUSE_DECL (clauses);
+                 else
+                   OMP_CLAUSE_DEFAULT_KIND (c)
+                     = OMP_CLAUSE_DEFAULT_KIND (clauses);
+                 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
+                 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] = c;
+               }
              s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
              break;
            }
@@ -1585,9 +1629,10 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
            }
          s = C_OMP_CLAUSE_SPLIT_PARALLEL;
          break;
-       /* Reduction is allowed on simd, for, parallel, sections and teams.
-          Duplicate it on all of them, but omit on for or sections if
-          parallel is present.  */
+       /* Reduction is allowed on simd, for, parallel, sections, taskloop
+          and teams.  Duplicate it on all of them, but omit on for or
+          sections if parallel is present.  If taskloop is combined with
+          parallel, omit it on parallel.  */
        case OMP_CLAUSE_REDUCTION:
          if (OMP_CLAUSE_REDUCTION_TASK (clauses))
            {
@@ -1649,8 +1694,12 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
              else
                s = C_OMP_CLAUSE_SPLIT_FOR;
            }
-         else if (code == OMP_SECTIONS || code == OMP_PARALLEL)
+         else if (code == OMP_SECTIONS
+                  || code == OMP_PARALLEL
+                  || code == OMP_MASTER)
            s = C_OMP_CLAUSE_SPLIT_PARALLEL;
+         else if (code == OMP_TASKLOOP)
+           s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
          else if (code == OMP_SIMD)
            {
              if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
@@ -1763,7 +1812,22 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
            }
          if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
              != 0)
-           s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
+           {
+             if ((mask & (OMP_CLAUSE_MASK_1
+                          << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
+               {
+                 c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
+                                       OMP_CLAUSE_IF);
+                 OMP_CLAUSE_IF_MODIFIER (c)
+                   = OMP_CLAUSE_IF_MODIFIER (clauses);
+                 OMP_CLAUSE_IF_EXPR (c) = OMP_CLAUSE_IF_EXPR (clauses);
+                 OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
+                 cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP] = c;
+                 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
+               }
+             else
+               s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
+           }
          else if ((mask & (OMP_CLAUSE_MASK_1
                            << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
            {
index e4fcbc43c571660bb866757974a43f0bfcbda232..838ee68df6b3da85b4073a7f198498f4379c6cdc 100644 (file)
@@ -1,3 +1,15 @@
+2018-10-18  Jakub Jelinek  <jakub@redhat.com>
+
+       * c-parser.c (c_parser_omp_taskloop): Add forward declaration.
+       Disallow in_reduction clause when combined with parallel master.
+       (c_parser_omp_master): Add p_name, mask and cclauses arguments.
+       Allow to be called while parsing combined parallel master.
+       Parse combined master taskloop{, simd}.
+       (c_parser_omp_parallel): Parse combined
+       parallel master{, taskloop{, simd}} constructs.
+       (c_parser_omp_construct) <case PRAGMA_OMP_MASTER>: Adjust
+       c_parser_omp_master caller.
+
 2018-10-17  Jakub Jelinek  <jakub@redhat.com>
 
        * c-parser.c (c_finish_taskloop_clauses): New function.
index 84036a9c049ed67ebd3664c5820d829703a3abe7..c9f9acf50135f5fc1b09dd72ba947a0a6b9c2082 100644 (file)
@@ -16804,6 +16804,9 @@ c_parser_omp_for (location_t loc, c_parser *parser,
   return ret;
 }
 
+static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
+                                  omp_clause_mask, tree *, bool *);
+
 /* OpenMP 2.5:
    # pragma omp master new-line
      structured-block
@@ -16812,9 +16815,52 @@ c_parser_omp_for (location_t loc, c_parser *parser,
 */
 
 static tree
-c_parser_omp_master (location_t loc, c_parser *parser, bool *if_p)
+c_parser_omp_master (location_t loc, c_parser *parser,
+                    char *p_name, omp_clause_mask mask, tree *cclauses,
+                    bool *if_p)
 {
-  c_parser_skip_to_pragma_eol (parser);
+  tree block, clauses, ret;
+
+  strcat (p_name, " master");
+
+  if (c_parser_next_token_is (parser, CPP_NAME))
+    {
+      const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+
+      if (strcmp (p, "taskloop") == 0)
+       {
+         tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
+         if (cclauses == NULL)
+           cclauses = cclauses_buf;
+
+         c_parser_consume_token (parser);
+         if (!flag_openmp)  /* flag_openmp_simd  */
+           return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
+                                         if_p);
+         block = c_begin_compound_stmt (true);
+         ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
+                                      if_p);
+         block = c_end_compound_stmt (loc, block, true);
+         if (ret == NULL_TREE)
+           return ret;
+         ret = c_finish_omp_master (loc, block);
+         return ret;
+       }
+    }
+  if (!flag_openmp)  /* flag_openmp_simd  */
+    {
+      c_parser_skip_to_pragma_eol (parser, false);
+      return NULL_TREE;
+    }
+
+  if (cclauses)
+    {
+      clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
+      omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
+    }
+  else
+    c_parser_skip_to_pragma_eol (parser);
+
   return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
                                                                  if_p));
 }
@@ -17076,19 +17122,38 @@ c_parser_omp_parallel (location_t loc, c_parser *parser,
       c_parser_skip_to_pragma_eol (parser);
       return NULL_TREE;
     }
-  else if (!flag_openmp)  /* flag_openmp_simd  */
-    {
-      c_parser_skip_to_pragma_eol (parser, false);
-      return NULL_TREE;
-    }
   else if (cclauses == NULL && c_parser_next_token_is (parser, CPP_NAME))
     {
       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
-      if (strcmp (p, "sections") == 0)
+      if (strcmp (p, "master") == 0)
        {
          tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
-         if (cclauses == NULL)
-           cclauses = cclauses_buf;
+         cclauses = cclauses_buf;
+
+         c_parser_consume_token (parser);
+         if (!flag_openmp)  /* flag_openmp_simd  */
+           return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
+                                       if_p);
+         block = c_begin_omp_parallel ();
+         tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
+                                         if_p);
+         stmt = c_finish_omp_parallel (loc,
+                                       cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
+                                       block);
+         OMP_PARALLEL_COMBINED (stmt) = 1;
+         if (ret == NULL)
+           return ret;
+         return stmt;
+       }
+      else if (!flag_openmp)  /* flag_openmp_simd  */
+       {
+         c_parser_skip_to_pragma_eol (parser, false);
+         return NULL_TREE;
+       }
+      else if (strcmp (p, "sections") == 0)
+       {
+         tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
+         cclauses = cclauses_buf;
 
          c_parser_consume_token (parser);
          block = c_begin_omp_parallel ();
@@ -17100,6 +17165,11 @@ c_parser_omp_parallel (location_t loc, c_parser *parser,
          return stmt;
        }
     }
+  else if (!flag_openmp)  /* flag_openmp_simd  */
+    {
+      c_parser_skip_to_pragma_eol (parser, false);
+      return NULL_TREE;
+    }
 
   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
   if (cclauses)
@@ -18892,6 +18962,10 @@ c_parser_omp_taskloop (location_t loc, c_parser *parser,
 
   strcat (p_name, " taskloop");
   mask |= OMP_TASKLOOP_CLAUSE_MASK;
+  /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
+     clause.  */
+  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
+    mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
 
   if (c_parser_next_token_is (parser, CPP_NAME))
     {
@@ -19003,7 +19077,8 @@ c_parser_omp_construct (c_parser *parser, bool *if_p)
       stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
       break;
     case PRAGMA_OMP_MASTER:
-      stmt = c_parser_omp_master (loc, parser, if_p);
+      strcpy (p_name, "#pragma omp");
+      stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
       break;
     case PRAGMA_OMP_PARALLEL:
       strcpy (p_name, "#pragma omp");
index 7d853b9f9d2a54d50c39ec6208317b6ddaec721b..63e41c8f7175fd322350ffb1cb97d5f7967e16ac 100644 (file)
@@ -1,3 +1,15 @@
+2018-10-18  Jakub Jelinek  <jakub@redhat.com>
+
+       * parser.c (cp_parser_omp_taskloop): Add forward declaration.
+       Disallow in_reduction clause when combined with parallel master.
+       (cp_parser_omp_master): Add p_name, mask and cclauses arguments.
+       Allow to be called while parsing combined parallel master.
+       Parse combined master taskloop{, simd}.
+       (cp_parser_omp_parallel): Parse combined
+       parallel master{, taskloop{, simd}} constructs.
+       (cp_parser_omp_construct) <case PRAGMA_OMP_MASTER>: Adjust
+       c_parser_omp_master caller.
+
 2018-10-17  Jakub Jelinek  <jakub@redhat.com>
 
        * semantics.c (finish_omp_reduction_clause): Call save_expr for
index f841bc6eeb576568fae6d7c077f8221b61aa0c22..ae92961634b2a4111ce318879e11bfe48c7df9ea 100644 (file)
@@ -36569,15 +36569,66 @@ cp_parser_omp_for (cp_parser *parser, cp_token *pragma_tok,
   return ret;
 }
 
+static tree cp_parser_omp_taskloop (cp_parser *, cp_token *, char *,
+                                   omp_clause_mask, tree *, bool *);
+
 /* OpenMP 2.5:
    # pragma omp master new-line
      structured-block  */
 
 static tree
-cp_parser_omp_master (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
+cp_parser_omp_master (cp_parser *parser, cp_token *pragma_tok,
+                     char *p_name, omp_clause_mask mask, tree *cclauses,
+                     bool *if_p)
 {
-  cp_parser_require_pragma_eol (parser, pragma_tok);
-  return c_finish_omp_master (input_location,
+  tree clauses, sb, ret;
+  unsigned int save;
+  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+
+  strcat (p_name, " master");
+
+  if (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 (p, "taskloop") == 0)
+       {
+         tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
+         if (cclauses == NULL)
+           cclauses = cclauses_buf;
+
+         cp_lexer_consume_token (parser->lexer);
+         if (!flag_openmp)  /* flag_openmp_simd  */
+           return cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask,
+                                          cclauses, if_p);
+         sb = begin_omp_structured_block ();
+         save = cp_parser_begin_omp_structured_block (parser);
+         ret = cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask,
+                                       cclauses, if_p);
+         cp_parser_end_omp_structured_block (parser, save);
+         tree body = finish_omp_structured_block (sb);
+         if (ret == NULL)
+           return ret;
+         return c_finish_omp_master (loc, body);
+       }
+    }
+  if (!flag_openmp)  /* flag_openmp_simd  */
+    {
+      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+      return NULL_TREE;
+    }
+
+  if (cclauses)
+    {
+      clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
+                                          false);
+      cp_omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
+    }
+  else
+    cp_parser_require_pragma_eol (parser, pragma_tok);
+
+  return c_finish_omp_master (loc,
                              cp_parser_omp_structured_block (parser, if_p));
 }
 
@@ -36819,16 +36870,34 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok,
       cp_parser_skip_to_pragma_eol (parser, pragma_tok);
       return NULL_TREE;
     }
-  else if (!flag_openmp)  /* flag_openmp_simd  */
-    {
-      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
-      return NULL_TREE;
-    }
   else if (cclauses == NULL && 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 (p, "sections") == 0)
+      if (strcmp (p, "master") == 0)
+       {
+         tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
+         cclauses = cclauses_buf;
+
+         cp_lexer_consume_token (parser->lexer);
+         block = begin_omp_parallel ();
+         save = cp_parser_begin_omp_structured_block (parser);
+         tree ret = cp_parser_omp_master (parser, pragma_tok, p_name, mask,
+                                          cclauses, if_p);
+         cp_parser_end_omp_structured_block (parser, save);
+         stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
+                                     block);
+         OMP_PARALLEL_COMBINED (stmt) = 1;
+         if (ret == NULL_TREE)
+           return ret;
+         return stmt;
+       }
+      else if (!flag_openmp)  /* flag_openmp_simd  */
+       {
+         cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+         return NULL_TREE;
+       }
+      else if (strcmp (p, "sections") == 0)
        {
          tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
          cclauses = cclauses_buf;
@@ -36844,6 +36913,11 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok,
          return stmt;
        }
     }
+  else if (!flag_openmp)  /* flag_openmp_simd  */
+    {
+      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+      return NULL_TREE;
+    }
 
   clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
                                       cclauses == NULL);
@@ -39089,6 +39163,10 @@ cp_parser_omp_taskloop (cp_parser *parser, cp_token *pragma_tok,
 
   strcat (p_name, " taskloop");
   mask |= OMP_TASKLOOP_CLAUSE_MASK;
+  /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
+     clause.  */
+  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
+    mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
 
   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
     {
@@ -39451,7 +39529,9 @@ cp_parser_omp_construct (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
                                if_p);
       break;
     case PRAGMA_OMP_MASTER:
-      stmt = cp_parser_omp_master (parser, pragma_tok, if_p);
+      strcpy (p_name, "#pragma omp");
+      stmt = cp_parser_omp_master (parser, pragma_tok, p_name, mask, NULL,
+                                  if_p);
       break;
     case PRAGMA_OMP_PARALLEL:
       strcpy (p_name, "#pragma omp");
index 3f355855bde6742f8e1633eb1e7ac92fed14ce00..0bb0435d720bbf52cd64495c96082c63ead0e5b2 100644 (file)
@@ -130,6 +130,8 @@ enum omp_region_type
 
   ORT_TASK     = 0x10,
   ORT_UNTIED_TASK = ORT_TASK | 1,
+  ORT_TASKLOOP  = ORT_TASK | 2,
+  ORT_UNTIED_TASKLOOP = ORT_UNTIED_TASK | 2,
 
   ORT_TEAMS    = 0x20,
   ORT_COMBINED_TEAMS = ORT_TEAMS | 1,
@@ -6992,6 +6994,8 @@ omp_default_clause (struct gimplify_omp_ctx *ctx, tree decl,
 
        if (ctx->region_type & ORT_PARALLEL)
          rtype = "parallel";
+       else if ((ctx->region_type & ORT_TASKLOOP) == ORT_TASKLOOP)
+         rtype = "taskloop";
        else if (ctx->region_type & ORT_TASK)
          rtype = "task";
        else if (ctx->region_type & ORT_TEAMS)
@@ -8976,6 +8980,31 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                          " or private in outer context", DECL_NAME (decl));
            }
        do_notice:
+         if ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
+             && outer_ctx
+             && outer_ctx->region_type == ORT_COMBINED_PARALLEL
+             && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
+                 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
+                 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE))
+           {
+             splay_tree_node on
+               = splay_tree_lookup (outer_ctx->variables,
+                                    (splay_tree_key)decl);
+             if (on == NULL || (on->value & GOVD_DATA_SHARE_CLASS) == 0)
+               {
+                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
+                     && TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF
+                     && (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
+                         || (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE
+                             && (TREE_CODE (TREE_TYPE (TREE_TYPE (decl)))
+                                 == POINTER_TYPE))))
+                   omp_firstprivatize_variable (outer_ctx, decl);
+                 else
+                   omp_add_variable (outer_ctx, decl,
+                                     GOVD_SEEN | GOVD_SHARED);
+                 omp_notice_variable (outer_ctx, decl, true);
+               }
+           }
          if (outer_ctx)
            omp_notice_variable (outer_ctx, decl, true);
          if (check_non_private
@@ -10421,9 +10450,9 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
       break;
     case OMP_TASKLOOP:
       if (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_UNTIED))
-       ort = ORT_UNTIED_TASK;
+       ort = ORT_UNTIED_TASKLOOP;
       else
-       ort = ORT_TASK;
+       ort = ORT_TASKLOOP;
       break;
     case OMP_SIMD:
       ort = ORT_SIMD;
@@ -10731,7 +10760,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
                      else if (omp_check_private (outer, decl, false))
                        outer = NULL;
                    }
-                 else if (((outer->region_type & ORT_TASK) != 0)
+                 else if (((outer->region_type & ORT_TASKLOOP)
+                           == ORT_TASKLOOP)
                           && outer->combined_loop
                           && !omp_check_private (gimplify_omp_ctxp,
                                                  decl, false))
@@ -10770,8 +10800,12 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
                                outer = NULL;
                            }
                          if (outer && outer->outer_context
-                             && (outer->outer_context->region_type
-                                 & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS)
+                             && ((outer->outer_context->region_type
+                                  & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS
+                                 || (((outer->region_type & ORT_TASKLOOP)
+                                      == ORT_TASKLOOP)
+                                     && (outer->outer_context->region_type
+                                         == ORT_COMBINED_PARALLEL))))
                            {
                              outer = outer->outer_context;
                              n = splay_tree_lookup (outer->variables,
@@ -10818,7 +10852,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
                      else if (omp_check_private (outer, decl, false))
                        outer = NULL;
                    }
-                 else if (((outer->region_type & ORT_TASK) != 0)
+                 else if (((outer->region_type & ORT_TASKLOOP)
+                           == ORT_TASKLOOP)
                           && outer->combined_loop
                           && !omp_check_private (gimplify_omp_ctxp,
                                                  decl, false))
@@ -10857,8 +10892,12 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
                                outer = NULL;
                            }
                          if (outer && outer->outer_context
-                             && (outer->outer_context->region_type
-                                 & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS)
+                             && ((outer->outer_context->region_type
+                                  & ORT_COMBINED_TEAMS) == ORT_COMBINED_TEAMS
+                                 || (((outer->region_type & ORT_TASKLOOP)
+                                      == ORT_TASKLOOP)
+                                     && (outer->outer_context->region_type
+                                         == ORT_COMBINED_PARALLEL))))
                            {
                              outer = outer->outer_context;
                              n = splay_tree_lookup (outer->variables,
index d134e31b3d2a10ab5176b30f35b1a26d2ebccd7e..5a471f84ec6d7fd360061a3d51c888637cac8061 100644 (file)
@@ -1,3 +1,17 @@
+2018-10-18  Jakub Jelinek  <jakub@redhat.com>
+
+       * c-c++-common/gomp/clauses-1.c (foo): Add ntm argument and
+       test if and nontemporal clauses on constructs with simd.
+       (bar): Add ntm and i3 arguments.  Test if and nontemporal clauses
+       on constructs with simd.  Change if clauses on some constructs from
+       specific to the particular constituents to one without a modifier.
+       Add new tests for combined host teams and for new parallel master
+       and {,parallel }master taskloop{, simd} combined constructs.
+       (baz): New function with host teams tests.
+       * c-c++-common/gomp/default-1.c: New test.
+       * c-c++-common/gomp/master-combined-1.c: New test.
+       * c-c++-common/gomp/master-combined-2.c: New test.
+
 2018-10-17  Jakub Jelinek  <jakub@redhat.com>
 
        * gcc.dg/gomp/reduction-2.c: New test.
index 1bbc1464216c080422499a0742f035d65580a0b5..652270cc0bdd381a9e1f5348138928cfe5cdbd34 100644 (file)
@@ -9,7 +9,7 @@ int f, l, ll, r, r2;
 
 void
 foo (int d, int m, int i1, int i2, int p, int *idp, int s,
-     int nte, int tl, int nth, int g, int nta, int fi, int pp, int *q)
+     int nte, int tl, int nth, int g, int nta, int fi, int pp, int *q, int ntm)
 {
   #pragma omp distribute parallel for \
     private (p) firstprivate (f) collapse(1) dist_schedule(static, 16) \
@@ -19,26 +19,50 @@ foo (int d, int m, int i1, int i2, int p, int *idp, int s,
     ll++;
   #pragma omp distribute parallel for simd \
     private (p) firstprivate (f) collapse(1) dist_schedule(static, 16) \
-    if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) \
-    lastprivate (l) schedule(static, 4) \
+    if (parallel: i2) if(simd: i1) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) \
+    lastprivate (l) schedule(static, 4) nontemporal(ntm) \
     safelen(8) simdlen(4) aligned(q: 32)
   for (int i = 0; i < 64; i++)
     ll++;
   #pragma omp distribute simd \
     private (p) firstprivate (f) collapse(1) dist_schedule(static, 16) \
-    safelen(8) simdlen(4) aligned(q: 32) reduction(+:r)
+    safelen(8) simdlen(4) aligned(q: 32) reduction(+:r) if(i1) nontemporal(ntm)
   for (int i = 0; i < 64; i++)
     ll++;
 }
 #pragma omp end declare target
 
 void
-bar (int d, int m, int i1, int i2, int p, int *idp, int s,
-     int nte, int tl, int nth, int g, int nta, int fi, int pp, int *q, int *dd)
+baz (int d, int m, int i1, int i2, int p, int *idp, int s,
+     int nte, int tl, int nth, int g, int nta, int fi, int pp, int *q, int ntm)
+{
+  #pragma omp distribute parallel for \
+    private (p) firstprivate (f) collapse(1) dist_schedule(static, 16) \
+    if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) \
+    lastprivate (l) schedule(static, 4) copyin(t)
+  for (int i = 0; i < 64; i++)
+    ll++;
+  #pragma omp distribute parallel for simd \
+    private (p) firstprivate (f) collapse(1) dist_schedule(static, 16) \
+    if (parallel: i2) if(simd: i1) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) \
+    lastprivate (l) schedule(static, 4) nontemporal(ntm) \
+    safelen(8) simdlen(4) aligned(q: 32) copyin(t)
+  for (int i = 0; i < 64; i++)
+    ll++;
+  #pragma omp distribute simd \
+    private (p) firstprivate (f) collapse(1) dist_schedule(static, 16) \
+    safelen(8) simdlen(4) aligned(q: 32) reduction(+:r) if(i1) nontemporal(ntm)
+  for (int i = 0; i < 64; i++)
+    ll++;
+}
+
+void
+bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
+     int nte, int tl, int nth, int g, int nta, int fi, int pp, int *q, int *dd, int ntm)
 {
   #pragma omp for simd \
     private (p) firstprivate (f) lastprivate (l) linear (ll:1) reduction(+:r) schedule(static, 4) collapse(1) nowait \
-    safelen(8) simdlen(4) aligned(q: 32)
+    safelen(8) simdlen(4) aligned(q: 32) nontemporal(ntm) if(i1)
   for (int i = 0; i < 64; i++)
     ll++;
   #pragma omp parallel for \
@@ -47,9 +71,9 @@ bar (int d, int m, int i1, int i2, int p, int *idp, int s,
   for (int i = 0; i < 64; i++)
     ll++;
   #pragma omp parallel for simd \
-    private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) copyin(t) reduction(+:r) num_threads (nth) proc_bind(spread) \
+    private (p) firstprivate (f) if (i2) default(shared) shared(s) copyin(t) reduction(+:r) num_threads (nth) proc_bind(spread) \
     lastprivate (l) linear (ll:1) schedule(static, 4) collapse(1) \
-    safelen(8) simdlen(4) aligned(q: 32)
+    safelen(8) simdlen(4) aligned(q: 32) nontemporal(ntm)
   for (int i = 0; i < 64; i++)
     ll++;
   #pragma omp parallel sections \
@@ -76,7 +100,7 @@ bar (int d, int m, int i1, int i2, int p, int *idp, int s,
     device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \
     if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) \
     lastprivate (l) linear (ll:1) schedule(static, 4) collapse(1) \
-    safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0])
+    safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0]) nontemporal(ntm) if (simd: i3)
   for (int i = 0; i < 64; i++)
     ll++;
   #pragma omp target teams \
@@ -103,38 +127,38 @@ bar (int d, int m, int i1, int i2, int p, int *idp, int s,
     collapse(1) dist_schedule(static, 16) \
     if (parallel: i2) num_threads (nth) proc_bind(spread) \
     lastprivate (l) schedule(static, 4) \
-    safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0])
+    safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0]) nontemporal(ntm) if (simd: i3)
   for (int i = 0; i < 64; i++)
     ll++;
   #pragma omp target teams distribute simd \
-    device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \
+    device(d) map (tofrom: m) if (i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \
     shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
     collapse(1) dist_schedule(static, 16) \
-    safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0])
+    safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0]) nontemporal(ntm)
   for (int i = 0; i < 64; i++)
     ll++;
   #pragma omp target simd \
     device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \
     safelen(8) simdlen(4) lastprivate (l) linear(ll: 1) aligned(q: 32) reduction(+:r) \
-     nowait depend(inout: dd[0])
+     nowait depend(inout: dd[0]) nontemporal(ntm) if(simd:i3)
   for (int i = 0; i < 64; i++)
     ll++;
   #pragma omp taskgroup task_reduction(+:r2)
   #pragma omp taskloop simd \
-    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) final(fi) mergeable priority (pp) \
-    safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2)
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) if(simd: i2) final(fi) mergeable priority (pp) \
+    safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm)
   for (int i = 0; i < 64; i++)
     ll++;
   #pragma omp taskgroup task_reduction(+:r)
   #pragma omp taskloop simd \
-    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) final(fi) mergeable nogroup priority (pp) \
-    safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) in_reduction(+:r)
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(i1) final(fi) mergeable nogroup priority (pp) \
+    safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) in_reduction(+:r) nontemporal(ntm)
   for (int i = 0; i < 64; i++)
     ll++;
   #pragma omp taskwait
   #pragma omp taskloop simd \
     private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) if(taskloop: i1) final(fi) priority (pp) \
-    safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(+:r)
+    safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(+:r) if (simd: i3) nontemporal(ntm)
   for (int i = 0; i < 64; i++)
     ll++;
   #pragma omp target nowait depend(inout: dd[0])
@@ -157,14 +181,83 @@ bar (int d, int m, int i1, int i2, int p, int *idp, int s,
     collapse(1) dist_schedule(static, 16) \
     if (parallel: i2) num_threads (nth) proc_bind(spread) \
     lastprivate (l) schedule(static, 4) \
-    safelen(8) simdlen(4) aligned(q: 32)
+    safelen(8) simdlen(4) aligned(q: 32) if (simd: i3) nontemporal(ntm)
   for (int i = 0; i < 64; i++)
     ll++;
   #pragma omp target
   #pragma omp teams distribute simd \
     private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
     collapse(1) dist_schedule(static, 16) \
-    safelen(8) simdlen(4) aligned(q: 32)
+    safelen(8) simdlen(4) aligned(q: 32) if(i3) nontemporal(ntm)
+  for (int i = 0; i < 64; i++)
+    ll++;
+  #pragma omp teams distribute parallel for \
+    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
+    collapse(1) dist_schedule(static, 16) \
+    if (parallel: i2) num_threads (nth) proc_bind(spread) \
+    lastprivate (l) schedule(static, 4) copyin(t)
+  for (int i = 0; i < 64; i++)
+    ll++;
+  #pragma omp teams distribute parallel for simd \
+    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
+    collapse(1) dist_schedule(static, 16) \
+    if (parallel: i2) num_threads (nth) proc_bind(spread) \
+    lastprivate (l) schedule(static, 4) \
+    safelen(8) simdlen(4) aligned(q: 32) if (simd: i3) nontemporal(ntm) copyin(t)
+  for (int i = 0; i < 64; i++)
+    ll++;
+  #pragma omp teams distribute simd \
+    private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
+    collapse(1) dist_schedule(static, 16) \
+    safelen(8) simdlen(4) aligned(q: 32) if(i3) nontemporal(ntm)
+  for (int i = 0; i < 64; i++)
+    ll++;
+  #pragma omp parallel master \
+    private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) reduction(+:r) \
+    num_threads (nth) proc_bind(spread) copyin(t)
+    ;
+  #pragma omp taskgroup task_reduction (+:r2)
+  #pragma omp master taskloop \
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) final(fi) mergeable priority (pp) \
+    reduction(default, +:r) in_reduction(+:r2)
+  for (int i = 0; i < 64; i++)
+    ll++;
+  #pragma omp taskgroup task_reduction (+:r2)
+  #pragma omp master taskloop simd \
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) if(simd: i2) final(fi) mergeable priority (pp) \
+    safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm)
+  for (int i = 0; i < 64; i++)
+    ll++;
+  #pragma omp parallel master taskloop \
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) final(fi) mergeable priority (pp) \
+    reduction(default, +:r) if (parallel: i2) num_threads (nth) proc_bind(spread) copyin(t)
+  for (int i = 0; i < 64; i++)
+    ll++;
+  #pragma omp parallel master taskloop simd \
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) if(simd: i2) final(fi) mergeable priority (pp) \
+    safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) nontemporal(ntm) if (parallel: i2) num_threads (nth) proc_bind(spread) copyin(t)
+  for (int i = 0; i < 64; i++)
+    ll++;
+  #pragma omp taskgroup task_reduction (+:r2)
+  #pragma omp master taskloop \
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp) \
+    reduction(default, +:r) in_reduction(+:r2)
+  for (int i = 0; i < 64; i++)
+    ll++;
+  #pragma omp taskgroup task_reduction (+:r2)
+  #pragma omp master taskloop simd \
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp) \
+    safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm)
+  for (int i = 0; i < 64; i++)
+    ll++;
+  #pragma omp parallel master taskloop \
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp) \
+    reduction(default, +:r) num_threads (nth) proc_bind(spread) copyin(t)
+  for (int i = 0; i < 64; i++)
+    ll++;
+  #pragma omp parallel master taskloop simd \
+    private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp) \
+    safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) nontemporal(ntm) num_threads (nth) proc_bind(spread) copyin(t)
   for (int i = 0; i < 64; i++)
     ll++;
 }
diff --git a/gcc/testsuite/c-c++-common/gomp/default-1.c b/gcc/testsuite/c-c++-common/gomp/default-1.c
new file mode 100644 (file)
index 0000000..6525483
--- /dev/null
@@ -0,0 +1,22 @@
+void
+foo (void)
+{
+  int x = 0, i;
+  #pragma omp task default(none)       /* { dg-error "enclosing 'task'" } */
+  {
+    x++;       /* { dg-error "'x' not specified in enclosing 'task'" } */
+  }
+  #pragma omp taskloop default(none)   /* { dg-error "enclosing 'taskloop'" } */
+  for (i = 0; i < 64; i++)
+    {
+      x++;     /* { dg-error "'x' not specified in enclosing 'taskloop'" } */
+    }
+  #pragma omp teams default(none)      /* { dg-error "enclosing 'teams'" } */
+  {
+    x++;       /* { dg-error "'x' not specified in enclosing 'teams'" } */
+  }
+  #pragma omp parallel default(none)   /* { dg-error "enclosing 'parallel'" } */
+  {
+    x++;       /* { dg-error "'x' not specified in enclosing 'parallel'" } */
+  }
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/master-combined-1.c b/gcc/testsuite/c-c++-common/gomp/master-combined-1.c
new file mode 100644 (file)
index 0000000..b11f5db
--- /dev/null
@@ -0,0 +1,32 @@
+void bar (int *);
+
+void
+foo (int *a)
+{
+  int i, j, k, u = 0, v = 0, w = 0, x = 0, y = 0, z = 0;
+  #pragma omp parallel master default(none) private (k)
+  bar (&k);
+  #pragma omp parallel default(none) firstprivate(a) shared(x, y, z)
+  {
+    #pragma omp master taskloop reduction (+:x) default(none) firstprivate(a)
+    for (i = 0; i < 64; i++)
+      x += a[i];
+    #pragma omp master taskloop simd reduction (+:y) default(none) firstprivate(a) private (i)
+    for (i = 0; i < 64; i++)
+      y += a[i];
+    #pragma omp master taskloop simd collapse(2) reduction (+:z) default(none) firstprivate(a) private (i, j)
+    for (j = 0; j < 1; j++)
+      for (i = 0; i < 64; ++i)
+       z += a[i];
+  }
+  #pragma omp parallel master taskloop reduction (+:u) default(none) firstprivate(a)
+  for (i = 0; i < 64; i++)
+    u += a[i];
+  #pragma omp parallel master taskloop simd reduction (+:v) default(none) firstprivate(a)
+  for (i = 0; i < 64; i++)
+    v += a[i];
+  #pragma omp parallel master taskloop simd collapse(2) reduction (+:w) default(none) firstprivate(a)
+  for (j = 0; j < 1; j++)
+    for (i = 0; i < 64; ++i)
+      w += a[i];
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/master-combined-2.c b/gcc/testsuite/c-c++-common/gomp/master-combined-2.c
new file mode 100644 (file)
index 0000000..4f7b574
--- /dev/null
@@ -0,0 +1,13 @@
+void
+foo (int *a)
+{
+  int i, r = 0, s = 0;
+  #pragma omp taskgroup task_reduction(+:r)
+  #pragma omp parallel master taskloop in_reduction(+:r)       /* { dg-error "'in_reduction' is not valid for '#pragma omp parallel master taskloop'" } */
+  for (i = 0; i < 64; i++)
+    r += a[i];
+  #pragma omp taskgroup task_reduction(+:s)
+  #pragma omp parallel master taskloop simd in_reduction(+:s)  /* { dg-error "'in_reduction' is not valid for '#pragma omp parallel master taskloop simd'" } */
+  for (i = 0; i < 64; i++)
+    s += a[i];
+}
index cbab22f434421982056cbd8873e3704129923959..a58fc2cbf987917c741cdd68b3131986cfc097c1 100644 (file)
@@ -1,3 +1,9 @@
+2018-10-18  Jakub Jelinek  <jakub@redhat.com>
+
+       * testsuite/libgomp.c-c++-common/master-combined-1.c: New test.
+       * testsuite/libgomp.c-c++-common/taskloop-reduction-3.c: New test.
+       * testsuite/libgomp.c-c++-common/taskloop-reduction-4.c: New test.
+
 2018-10-16  Jakub Jelinek  <jakub@redhat.com>
 
        * task.c (GOMP_taskgroup_reduction_register): Add ialias.
diff --git a/libgomp/testsuite/libgomp.c-c++-common/master-combined-1.c b/libgomp/testsuite/libgomp.c-c++-common/master-combined-1.c
new file mode 100644 (file)
index 0000000..3e6da09
--- /dev/null
@@ -0,0 +1,66 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-std=c99" { target c } } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+#include <omp.h>
+#include <stdlib.h>
+
+#define N 64
+
+int
+main ()
+{
+  int p, *q, i, l;
+  int a[N];
+  q = a;
+  #pragma omp parallel master num_threads(4) private (p) shared(a)
+  {
+    int i;
+    p = omp_get_thread_num ();
+    if (p != 0)
+      abort ();
+    #pragma omp taskloop nogroup
+    for (i = 0; i < N; ++i)
+      {
+       if (omp_get_thread_num () >= 4)
+         abort ();
+       a[i] = i;
+      }
+  }
+  #pragma omp parallel num_threads(4)
+  {
+    #pragma omp master taskloop lastprivate (i, l) firstprivate (q)
+    for (i = 0; i != N; i = i + 1)
+      l = q[i];
+  }
+  if (i != N || l != N - 1)
+    abort ();
+  #pragma omp parallel master taskloop num_threads(4) \
+                      lastprivate (i, l) firstprivate (q)
+  for (i = 0; i < N - 5; i += 2)
+    if (q[i] != i)
+      abort ();
+    else
+      l = q[i];
+  if (i != N - 4 || l != N - 6)
+    abort ();
+  #pragma omp parallel master taskloop simd num_threads(4)
+  for (i = 0; i < N; i++)
+    a[i] = 2 * a[i];
+  if (i != N)
+    abort ();
+  #pragma omp parallel num_threads(4)
+  {
+    int j;
+    #pragma omp master taskloop simd collapse(2)
+    for (i = 0; i < 2; i += 2)
+      for (j = 0; j < N; j++)
+       a[j] = a[j] + 1;
+  }
+  for (i = 0; i < N; i++)
+    if (a[i] != 2 * i + 1)
+      abort ();
+  return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-3.c b/libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-3.c
new file mode 100644 (file)
index 0000000..5a1c154
--- /dev/null
@@ -0,0 +1,46 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-std=c99" { target c } } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+#define N 1024
+long int u[N], m, n;
+
+__attribute__((noipa)) void
+foo (void)
+{
+  int i;
+  #pragma omp taskloop simd reduction (+:m) grainsize (64)
+  for (i = 0; i < N; ++i)
+    m += u[i];
+}
+
+__attribute__((noipa)) void
+bar (int x)
+{
+  int i;
+  #pragma omp taskloop simd in_reduction (+:n) grainsize (64) nogroup
+  for (i = (x & 1) * (N / 2); i < (x & 1) * (N / 2) + (N / 2); i++)
+    n += 2 * u[i];
+}
+
+int
+main ()
+{
+  int i;
+  for (i = 0; i < N; ++i)
+    u[i] = i;
+  #pragma omp parallel master
+  {
+    foo ();
+    #pragma omp taskgroup task_reduction (+:n)
+    {
+      bar (0);
+      bar (1);
+    }
+  }
+  if (m != (long)(N - 1) * (N / 2) || n != (long)(N - 1) * N)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-4.c b/libgomp/testsuite/libgomp.c-c++-common/taskloop-reduction-4.c
new file mode 100644 (file)
index 0000000..c1c29b3
--- /dev/null
@@ -0,0 +1,65 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-std=c99" { target c } } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+#include <omp.h>
+#include <stdlib.h>
+
+#define N 1024
+long int u[N], m, n, o;
+
+__attribute__((noipa)) void
+foo (void)
+{
+  int i = -1;
+  #pragma omp master taskloop simd reduction (+:m) grainsize (64)
+  for (i = 0; i < N; ++i)
+    m += u[i];
+  if (i != (omp_get_thread_num () ? -1 : N))
+    abort ();
+}
+
+__attribute__((noipa)) void
+bar (int x)
+{
+  int i = -1;
+  #pragma omp master taskloop simd in_reduction (+:n) grainsize (64)
+  for (i = (x & 1) * (N / 2); i < (x & 1) * (N / 2) + (N / 2); i++)
+    n += 2 * u[i];
+  if (i != (omp_get_thread_num () ? -1 : (x & 1) * (N / 2) + (N / 2)))
+    abort ();
+}
+
+__attribute__((noipa)) void
+baz (void)
+{
+  int i;
+  #pragma omp parallel master taskloop simd reduction (+:o) grainsize (64)
+  for (i = 0; i < N; ++i)
+    o += u[i];
+  if (i != N)
+    abort ();
+}
+
+int
+main ()
+{
+  int i;
+  for (i = 0; i < N; ++i)
+    u[i] = i;
+  #pragma omp parallel
+  {
+    foo ();
+    #pragma omp taskgroup task_reduction (+:n)
+    {
+      bar (0);
+      bar (1);
+    }
+  }
+  baz ();
+  if (m != (long)(N - 1) * (N / 2) || n != (long)(N - 1) * N || o != m)
+    abort ();
+  return 0;
+}