[gomp5] simd if/nontemporal clauses parsing and cancel if modifier

Richard Biener richard.guenther@gmail.com
Wed May 9 10:00:00 GMT 2018


On Fri, May 4, 2018 at 8:37 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> This patch adds parsing of if and nontemporal clauses for simd construct
> and also adds parsing of (optional) cancel modifier for if clause on cancel
> directive.
>
> While nontemporal clause is just an optimization (we still want to use
> non-temporal stores (or even loads?) for those vars, what is the best way to
> do that?)

On GIMPLE we have gimple_assign_set_nontemporal_move so you could mark
all memory references involving those vars accordingly.  Not so easy if aliases
are involved I guess.  You'd need to apply this during lowering or
gimplification
then.  If you add some similar modifiers to GENERIC you could do it during
parsing.

> , simd if is not an optimization, if the expression evaluates to
> false at runtime, then we should just not vectorize; so probably we want to
> preserve it in some form until vectorization and include this condition next
> to where we emit checks for runtime aliasing or alignment etc.  Thoughts on
> how to do that?

Easiest would be to apply the versioning during OMP lowering/expansion.
You can then mark the 'else' loop as dont_vectorize.  Yes, this means we'll
get redundant versioning if the to be vectorized variant needs
versioning as well.
But we don't have any good infrastructure to do it in another way
(yet another IFN aka __builtin_vectorize_if () that the vectorizer could rely
on providing a scalar fallback?)

Richard.

> 2018-05-04  Jakub Jelinek  <jakub@redhat.com>
>
>         * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_NONTEMPORAL.
>         * tree.c (omp_clause_num_ops, omp_clause_code_name): Add nontemporal
>         clause entries.
>         (walk_tree_1): Handle OMP_CLAUSE_NONTEMPORAL.
>         * gimplify.c (enum gimplify_omp_var_data): Add GOVD_NONTEMPORAL.
>         (gimplify_scan_omp_clauses): Handle cancel and simd
>         OMP_CLAUSE_IF_MODIFIERs.  Handle OMP_CLAUSE_NONTEMPORAL.
>         (gimplify_adjust_omp_clauses_1): Ignore GOVD_NONTEMPORAL.
>         (gimplify_adjust_omp_clauses): Handle OMP_CLAUSE_NONTEMPORAL.
>         * omp-grid.c (grid_eliminate_combined_simd_part): Formatting fix.
>         Fix comment typos.
>         * tree-nested.c (convert_local_omp_clauses): Handle
>         OMP_CLAUSE_NONTEMPORAL.
>         (convert_nonlocal_omp_clauses): Likewise.  Remove useless test.
>         * tree-pretty-print.c (dump_omp_clause): Handle OMP_CLAUSE_NONTEMPORAL.
>         Handle cancel and simd OMP_CLAUSE_IF_MODIFIERs.
>         * omp-low.c (scan_sharing_clauses): Handle OMP_CLAUSE_NONTEMPORAL.
> gcc/c-family/
>         * c-omp.c (c_omp_split_clauses): Handle OMP_CLAUSE_NONTEMPORAL.  Handle
>         splitting OMP_CLAUSE_IF also to OMP_SIMD.
>         * c-pragma.h (enum pragma_omp_clause): Add
>         PRAGMA_OMP_CLAUSE_NONTEMPORAL.
> gcc/c/
>         * c-parser.c (c_parser_omp_clause_name): Handle nontemporal clause.
>         (c_parser_omp_clause_if): Handle cancel and simd modifiers.
>         (c_parser_omp_clause_nontemporal): New function.
>         (c_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_NONTEMPORAL.
>         (OMP_SIMD_CLAUSE_MASK): Add if and nontemporal clauses.
>         * c-typeck.c (c_finish_omp_cancel): Diagnose if clause with modifier
>         other than cancel.
>         (c_finish_omp_clauses): Handle OMP_CLAUSE_NONTEMPORAL.
> gcc/cp/
>         * parser.c (cp_parser_omp_clause_name): Handle nontemporal clause.
>         (cp_parser_omp_clause_if): Handle cancel and simd modifiers.
>         (cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_NONTEMPORAL.
>         (OMP_SIMD_CLAUSE_MASK): Add if and nontemporal clauses.
>         * semantics.c (finish_omp_clauses): Diagnose if clause with modifier
>         other than cancel.
>         (finish_omp_cancel): Handle OMP_CLAUSE_NONTEMPORAL.
>         * pt.c (tsubst_omp_clauses): Likewise.
> gcc/testsuite/
>         * c-c++-common/gomp/if-1.c (foo): Add some further tests.
>         * c-c++-common/gomp/if-2.c (foo): Likewise.  Expect slightly different
>         diagnostics wording in one case.
>         * c-c++-common/gomp/if-3.c: New test.
>         * c-c++-common/gomp/nontemporal-1.c: New test.
> libgomp/
>         * testsuite/libgomp.c/cancel-for-2.c (foo): Use cancel modifier
>         in some cases.
>
> --- gcc/tree-core.h.jj  2018-05-02 17:29:55.902260817 +0200
> +++ gcc/tree-core.h     2018-05-04 15:13:22.384614499 +0200
> @@ -293,6 +293,9 @@ enum omp_clause_code {
>    /* OpenMP clause: depend ({in,out,inout}:variable-list).  */
>    OMP_CLAUSE_DEPEND,
>
> +  /* OpenMP clause: nontemporal (variable-list).  */
> +  OMP_CLAUSE_NONTEMPORAL,
> +
>    /* OpenMP clause: uniform (argument-list).  */
>    OMP_CLAUSE_UNIFORM,
>
> --- gcc/tree.c.jj       2018-04-30 13:49:44.692824652 +0200
> +++ gcc/tree.c  2018-05-04 19:08:55.309273302 +0200
> @@ -289,6 +289,7 @@ unsigned const char omp_clause_num_ops[]
>    3, /* OMP_CLAUSE_LINEAR  */
>    2, /* OMP_CLAUSE_ALIGNED  */
>    1, /* OMP_CLAUSE_DEPEND  */
> +  1, /* OMP_CLAUSE_NONTEMPORAL  */
>    1, /* OMP_CLAUSE_UNIFORM  */
>    1, /* OMP_CLAUSE_TO_DECLARE  */
>    1, /* OMP_CLAUSE_LINK  */
> @@ -362,6 +363,7 @@ const char * const omp_clause_code_name[
>    "linear",
>    "aligned",
>    "depend",
> +  "nontemporal",
>    "uniform",
>    "to",
>    "link",
> @@ -11528,6 +11530,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func
>         case OMP_CLAUSE_SCHEDULE:
>         case OMP_CLAUSE_UNIFORM:
>         case OMP_CLAUSE_DEPEND:
> +       case OMP_CLAUSE_NONTEMPORAL:
>         case OMP_CLAUSE_NUM_TEAMS:
>         case OMP_CLAUSE_THREAD_LIMIT:
>         case OMP_CLAUSE_DEVICE:
> --- gcc/gimplify.c.jj   2018-05-03 15:22:54.521416751 +0200
> +++ gcc/gimplify.c      2018-05-04 19:08:55.309273302 +0200
> @@ -111,6 +111,8 @@ enum gimplify_omp_var_data
>    /* Flag for GOVD_MAP: only copy back.  */
>    GOVD_MAP_FROM_ONLY = 2097152,
>
> +  GOVD_NONTEMPORAL = 4194304,
> +
>    GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
>                            | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
>                            | GOVD_LOCAL)
> @@ -8558,7 +8560,9 @@ gimplify_scan_omp_clauses (tree *list_p,
>               for (int i = 0; i < 2; i++)
>                 switch (i ? OMP_CLAUSE_IF_MODIFIER (c) : code)
>                   {
> +                 case VOID_CST: p[i] = "cancel"; break;
>                   case OMP_PARALLEL: p[i] = "parallel"; break;
> +                 case OMP_SIMD: p[i] = "simd"; break;
>                   case OMP_TASK: p[i] = "task"; break;
>                   case OMP_TASKLOOP: p[i] = "taskloop"; break;
>                   case OMP_TARGET_DATA: p[i] = "target data"; break;
> @@ -8713,6 +8717,16 @@ gimplify_scan_omp_clauses (tree *list_p,
>             omp_add_variable (ctx, decl, GOVD_ALIGNED);
>           break;
>
> +       case OMP_CLAUSE_NONTEMPORAL:
> +         decl = OMP_CLAUSE_DECL (c);
> +         if (error_operand_p (decl))
> +           {
> +             remove = true;
> +             break;
> +           }
> +         omp_add_variable (ctx, decl, GOVD_NONTEMPORAL);
> +         break;
> +
>         case OMP_CLAUSE_DEFAULT:
>           ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
>           break;
> @@ -8937,7 +8951,7 @@ gimplify_adjust_omp_clauses_1 (splay_tre
>      }
>    else if (flags & GOVD_LASTPRIVATE)
>      code = OMP_CLAUSE_LASTPRIVATE;
> -  else if (flags & GOVD_ALIGNED)
> +  else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
>      return 0;
>    else
>      gcc_unreachable ();
> @@ -9234,6 +9248,12 @@ gimplify_adjust_omp_clauses (gimple_seq
>             }
>           break;
>
> +       case OMP_CLAUSE_NONTEMPORAL:
> +         decl = OMP_CLAUSE_DECL (c);
> +         n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
> +         remove = n == NULL || !(n->value & GOVD_SEEN);
> +         break;
> +
>         case OMP_CLAUSE_MAP:
>           if (code == OMP_TARGET_EXIT_DATA
>               && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER)
> --- gcc/omp-grid.c.jj   2018-04-30 13:49:53.225843055 +0200
> +++ gcc/omp-grid.c      2018-05-04 19:08:55.309273302 +0200
> @@ -1053,8 +1053,8 @@ grid_eliminate_combined_simd_part (gomp_
>    while (*tgt)
>      tgt = &OMP_CLAUSE_CHAIN (*tgt);
>
> -  /* Copy over all clauses, except for linaer clauses, which are turned into
> -     private clauses, and all other simd-specificl clauses, which are
> +  /* Copy over all clauses, except for linear clauses, which are turned into
> +     private clauses, and all other simd-specific clauses, which are
>       ignored.  */
>    tree *pc = gimple_omp_for_clauses_ptr (simd);
>    while (*pc)
> @@ -1083,7 +1083,7 @@ grid_eliminate_combined_simd_part (gomp_
>           *pc = OMP_CLAUSE_CHAIN (c);
>           OMP_CLAUSE_CHAIN (c) = NULL;
>           *tgt = c;
> -         tgt = &OMP_CLAUSE_CHAIN(c);
> +         tgt = &OMP_CLAUSE_CHAIN (c);
>           break;
>         }
>      }
> --- gcc/tree-nested.c.jj        2018-04-30 14:21:00.903020898 +0200
> +++ gcc/tree-nested.c   2018-05-04 19:08:55.309273302 +0200
> @@ -1261,6 +1261,8 @@ convert_nonlocal_omp_clauses (tree *pcla
>               convert_nonlocal_reference_op
>                 (&OMP_CLAUSE_ALIGNED_ALIGNMENT (clause), &dummy, wi);
>             }
> +         /* FALLTHRU */
> +       case OMP_CLAUSE_NONTEMPORAL:
>           /* Like do_decl_clause, but don't add any suppression.  */
>           decl = OMP_CLAUSE_DECL (clause);
>           if (VAR_P (decl)
> @@ -1269,8 +1271,7 @@ convert_nonlocal_omp_clauses (tree *pcla
>           if (decl_function_context (decl) != info->context)
>             {
>               OMP_CLAUSE_DECL (clause) = get_nonlocal_debug_decl (info, decl);
> -             if (OMP_CLAUSE_CODE (clause) != OMP_CLAUSE_PRIVATE)
> -               need_chain = true;
> +             need_chain = true;
>             }
>           break;
>
> @@ -1962,6 +1963,8 @@ convert_local_omp_clauses (tree *pclause
>               convert_local_reference_op
>                 (&OMP_CLAUSE_ALIGNED_ALIGNMENT (clause), &dummy, wi);
>             }
> +         /* FALLTHRU */
> +       case OMP_CLAUSE_NONTEMPORAL:
>           /* Like do_decl_clause, but don't add any suppression.  */
>           decl = OMP_CLAUSE_DECL (clause);
>           if (VAR_P (decl)
> --- gcc/tree-pretty-print.c.jj  2018-05-02 17:35:03.111530014 +0200
> +++ gcc/tree-pretty-print.c     2018-05-04 19:08:55.309273302 +0200
> @@ -434,6 +434,9 @@ dump_omp_clause (pretty_printer *pp, tre
>      case OMP_CLAUSE_LINK:
>        name = "link";
>        goto print_remap;
> +    case OMP_CLAUSE_NONTEMPORAL:
> +      name = "nontemporal";
> +      goto print_remap;
>    print_remap:
>        pp_string (pp, name);
>        pp_left_paren (pp);
> @@ -466,6 +469,8 @@ dump_omp_clause (pretty_printer *pp, tre
>         {
>         case ERROR_MARK: break;
> +       case VOID_CST: pp_string (pp, "cancel:"); break;
>         case OMP_PARALLEL: pp_string (pp, "parallel:"); break;
> +       case OMP_SIMD: pp_string (pp, "simd:"); break;
>         case OMP_TASK: pp_string (pp, "task:"); break;
>         case OMP_TASKLOOP: pp_string (pp, "taskloop:"); break;
>         case OMP_TARGET_DATA: pp_string (pp, "target data:"); break;
> --- gcc/omp-low.c.jj    2018-04-30 13:50:11.956883451 +0200
> +++ gcc/omp-low.c       2018-05-04 19:08:55.309273302 +0200
> @@ -1328,6 +1328,7 @@ scan_sharing_clauses (tree clauses, omp_
>         case OMP_CLAUSE_TILE:
>         case OMP_CLAUSE__SIMT_:
>         case OMP_CLAUSE_DEFAULT:
> +       case OMP_CLAUSE_NONTEMPORAL:
>           break;
>
>         case OMP_CLAUSE_ALIGNED:
> @@ -1486,6 +1487,7 @@ scan_sharing_clauses (tree clauses, omp_
>         case OMP_CLAUSE_NOGROUP:
>         case OMP_CLAUSE_DEFAULTMAP:
>         case OMP_CLAUSE_USE_DEVICE_PTR:
> +       case OMP_CLAUSE_NONTEMPORAL:
>         case OMP_CLAUSE_ASYNC:
>         case OMP_CLAUSE_WAIT:
>         case OMP_CLAUSE_NUM_GANGS:
> --- gcc/c-family/c-omp.c.jj     2018-04-30 15:20:48.766279152 +0200
> +++ gcc/c-family/c-omp.c        2018-05-04 19:08:55.309273302 +0200
> @@ -1185,6 +1185,7 @@ c_omp_split_clauses (location_t loc, enu
>         case OMP_CLAUSE_SAFELEN:
>         case OMP_CLAUSE_SIMDLEN:
>         case OMP_CLAUSE_ALIGNED:
> +       case OMP_CLAUSE_NONTEMPORAL:
>           s = C_OMP_CLAUSE_SPLIT_SIMD;
>           break;
>         case OMP_CLAUSE_GRAINSIZE:
> @@ -1484,6 +1485,74 @@ c_omp_split_clauses (location_t loc, enu
>             s = C_OMP_CLAUSE_SPLIT_TEAMS;
>           break;
>         case OMP_CLAUSE_IF:
> +         if (OMP_CLAUSE_IF_MODIFIER (clauses) != ERROR_MARK)
> +           {
> +             s = C_OMP_CLAUSE_SPLIT_COUNT;
> +             switch (OMP_CLAUSE_IF_MODIFIER (clauses))
> +               {
> +               case OMP_PARALLEL:
> +                 if ((mask & (OMP_CLAUSE_MASK_1
> +                              << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
> +                   s = C_OMP_CLAUSE_SPLIT_PARALLEL;
> +                 break;
> +               case OMP_SIMD:
> +                 if (code == OMP_SIMD)
> +                   s = C_OMP_CLAUSE_SPLIT_SIMD;
> +                 break;
> +               case OMP_TASKLOOP:
> +                 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
> +                     != 0)
> +                   s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
> +                 break;
> +               case OMP_TARGET:
> +                 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP))
> +                     != 0)
> +                   s = C_OMP_CLAUSE_SPLIT_TARGET;
> +                 break;
> +               default:
> +                 break;
> +               }
> +             if (s != C_OMP_CLAUSE_SPLIT_COUNT)
> +               break;
> +             /* Error-recovery here, invalid if-modifier specified, add the
> +                clause to just one construct.  */
> +             if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0)
> +               s = C_OMP_CLAUSE_SPLIT_TARGET;
> +             else if ((mask & (OMP_CLAUSE_MASK_1
> +                               << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
> +               s = C_OMP_CLAUSE_SPLIT_PARALLEL;
> +             else if ((mask & (OMP_CLAUSE_MASK_1
> +                               << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0)
> +               s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
> +             else if (code == OMP_SIMD)
> +               s = C_OMP_CLAUSE_SPLIT_SIMD;
> +             else
> +               gcc_unreachable ();
> +             break;
> +           }
> +         /* Otherwise, duplicate if clause to all constructs.  */
> +         if (code == OMP_SIMD)
> +           {
> +             if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)
> +                          | (OMP_CLAUSE_MASK_1
> +                             << PRAGMA_OMP_CLAUSE_NUM_THREADS)
> +                          | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP)))
> +                 != 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_SIMD];
> +                 cclauses[C_OMP_CLAUSE_SPLIT_SIMD] = c;
> +               }
> +             else
> +               {
> +                 s = C_OMP_CLAUSE_SPLIT_SIMD;
> +                 break;
> +               }
> +           }
>           if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
>               != 0)
>             s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
> @@ -1493,29 +1562,14 @@ c_omp_split_clauses (location_t loc, enu
>               if ((mask & (OMP_CLAUSE_MASK_1
>                            << PRAGMA_OMP_CLAUSE_MAP)) != 0)
>                 {
> -                 if (OMP_CLAUSE_IF_MODIFIER (clauses) == OMP_PARALLEL)
> -                   s = C_OMP_CLAUSE_SPLIT_PARALLEL;
> -                 else if (OMP_CLAUSE_IF_MODIFIER (clauses) == OMP_TARGET)
> -                   s = C_OMP_CLAUSE_SPLIT_TARGET;
> -                 else if (OMP_CLAUSE_IF_MODIFIER (clauses) == ERROR_MARK)
> -                   {
> -                     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_TARGET];
> -                     cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = c;
> -                     s = C_OMP_CLAUSE_SPLIT_PARALLEL;
> -                   }
> -                 else
> -                   {
> -                     error_at (OMP_CLAUSE_LOCATION (clauses),
> -                               "expected %<parallel%> or %<target%> %<if%> "
> -                               "clause modifier");
> -                     continue;
> -                   }
> +                 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_TARGET];
> +                 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = c;
> +                 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
>                 }
>               else
>                 s = C_OMP_CLAUSE_SPLIT_PARALLEL;
> --- gcc/c-family/c-pragma.h.jj  2018-04-30 13:49:30.025793022 +0200
> +++ gcc/c-family/c-pragma.h     2018-05-04 16:11:24.051925595 +0200
> @@ -105,6 +105,7 @@ enum pragma_omp_clause {
>    PRAGMA_OMP_CLAUSE_MAP,
>    PRAGMA_OMP_CLAUSE_MERGEABLE,
>    PRAGMA_OMP_CLAUSE_NOGROUP,
> +  PRAGMA_OMP_CLAUSE_NONTEMPORAL,
>    PRAGMA_OMP_CLAUSE_NOTINBRANCH,
>    PRAGMA_OMP_CLAUSE_NOWAIT,
>    PRAGMA_OMP_CLAUSE_NUM_TASKS,
> --- gcc/c/c-parser.c.jj 2018-05-03 17:16:15.668780501 +0200
> +++ gcc/c/c-parser.c    2018-05-04 19:24:36.795860291 +0200
> @@ -11300,6 +11300,8 @@ c_parser_omp_clause_name (c_parser *pars
>         case 'n':
>           if (!strcmp ("nogroup", p))
>             result = PRAGMA_OMP_CLAUSE_NOGROUP;
> +         else if (!strcmp ("nontemporal", p))
> +           result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
>           else if (!strcmp ("notinbranch", p))
>             result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
>           else if (!strcmp ("nowait", p))
> @@ -12031,7 +12033,11 @@ c_parser_omp_clause_final (c_parser *par
>
>     directive-name-modifier:
>       parallel | task | taskloop | target data | target | target update
> -     | target enter data | target exit data  */
> +     | target enter data | target exit data
> +
> +   OpenMP 5.0:
> +   directive-name-modifier:
> +     ... | simd | cancel  */
>
>  static tree
>  c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
> @@ -12047,8 +12053,12 @@ c_parser_omp_clause_if (c_parser *parser
>      {
>        const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
>        int n = 2;
> -      if (strcmp (p, "parallel") == 0)
> +      if (strcmp (p, "cancel") == 0)
> +       if_modifier = VOID_CST;
> +      else if (strcmp (p, "parallel") == 0)
>         if_modifier = OMP_PARALLEL;
> +      else if (strcmp (p, "simd") == 0)
> +       if_modifier = OMP_SIMD;
>        else if (strcmp (p, "task") == 0)
>         if_modifier = OMP_TASK;
>        else if (strcmp (p, "taskloop") == 0)
> @@ -12132,7 +12142,9 @@ c_parser_omp_clause_if (c_parser *parser
>             const char *p = NULL;
>             switch (if_modifier)
>               {
> +             case VOID_CST: p = "cancel"; break;
>               case OMP_PARALLEL: p = "parallel"; break;
> +             case OMP_SIMD: p = "simd"; break;
>               case OMP_TASK: p = "task"; break;
>               case OMP_TASKLOOP: p = "taskloop"; break;
>               case OMP_TARGET_DATA: p = "target data"; break;
> @@ -13612,6 +13624,15 @@ c_parser_omp_clause_linear (c_parser *pa
>    return nl;
>  }
>
> +/* OpenMP 5.0:
> +   nontemporal ( variable-list ) */
> +
> +static tree
> +c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
> +{
> +  return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
> +}
> +
>  /* OpenMP 4.0:
>     safelen ( constant-expression ) */
>
> @@ -14476,6 +14497,10 @@ c_parser_omp_all_clauses (c_parser *pars
>                                                 clauses);
>           c_name = "inbranch";
>           break;
> +       case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
> +         clauses = c_parser_omp_clause_nontemporal (parser, clauses);
> +         c_name = "nontemporal";
> +         break;
>         case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
>           clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
>                                                 clauses);
> @@ -16257,7 +16282,9 @@ omp_split_clauses (location_t loc, enum
>         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)      \
>         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)  \
>         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)    \
> -       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
> +       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)     \
> +       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)           \
> +       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL))
>
>  static tree
>  c_parser_omp_simd (location_t loc, c_parser *parser,
> --- gcc/c/c-typeck.c.jj 2018-04-30 13:49:35.956805813 +0200
> +++ gcc/c/c-typeck.c    2018-05-04 19:08:55.309273302 +0200
> @@ -12349,6 +12349,11 @@ c_finish_omp_cancel (location_t loc, tre
>    tree ifc = omp_find_clause (clauses, OMP_CLAUSE_IF);
>    if (ifc != NULL_TREE)
>      {
> +      if (OMP_CLAUSE_IF_MODIFIER (ifc) != ERROR_MARK
> +         && OMP_CLAUSE_IF_MODIFIER (ifc) != VOID_CST)
> +       error_at (OMP_CLAUSE_LOCATION (ifc),
> +                 "expected %<cancel%> %<if%> clause modifier");
> +
>        tree type = TREE_TYPE (OMP_CLAUSE_IF_EXPR (ifc));
>        ifc = fold_build2_loc (OMP_CLAUSE_LOCATION (ifc), NE_EXPR,
>                              boolean_type_node, OMP_CLAUSE_IF_EXPR (ifc),
> @@ -13521,6 +13526,16 @@ c_finish_omp_clauses (tree clauses, enum
>             bitmap_set_bit (&aligned_head, DECL_UID (t));
>           break;
>
> +       case OMP_CLAUSE_NONTEMPORAL:
> +         t = OMP_CLAUSE_DECL (c);
> +         if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
> +           {
> +             error_at (OMP_CLAUSE_LOCATION (c),
> +                       "%qE is not a variable in %<nontemporal%> clause", t);
> +             remove = true;
> +           }
> +         break;
> +
>         case OMP_CLAUSE_DEPEND:
>           t = OMP_CLAUSE_DECL (c);
>           if (t == NULL_TREE)
> --- gcc/cp/parser.c.jj  2018-05-03 17:18:14.432877678 +0200
> +++ gcc/cp/parser.c     2018-05-04 19:28:11.231064426 +0200
> @@ -31339,6 +31339,8 @@ cp_parser_omp_clause_name (cp_parser *pa
>         case 'n':
>           if (!strcmp ("nogroup", p))
>             result = PRAGMA_OMP_CLAUSE_NOGROUP;
> +         else if (!strcmp ("nontemporal", p))
> +           result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
>           else if (!strcmp ("notinbranch", p))
>             result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
>           else if (!strcmp ("nowait", p))
> @@ -32233,7 +32235,11 @@ cp_parser_omp_clause_final (cp_parser *p
>
>     directive-name-modifier:
>       parallel | task | taskloop | target data | target | target update
> -     | target enter data | target exit data  */
> +     | target enter data | target exit data
> +
> +   OpenMP 5.0:
> +   directive-name-modifier:
> +     ... | simd | cancel  */
>
>  static tree
>  cp_parser_omp_clause_if (cp_parser *parser, tree list, location_t location,
> @@ -32252,8 +32258,12 @@ cp_parser_omp_clause_if (cp_parser *pars
>        const char *p = IDENTIFIER_POINTER (id);
>        int n = 2;
>
> -      if (strcmp ("parallel", p) == 0)
> +      if (strcmp ("cancel", p) == 0)
> +       if_modifier = VOID_CST;
> +      else if (strcmp ("parallel", p) == 0)
>         if_modifier = OMP_PARALLEL;
> +      else if (strcmp ("simd", p) == 0)
> +       if_modifier = OMP_SIMD;
>        else if (strcmp ("task", p) == 0)
>         if_modifier = OMP_TASK;
>        else if (strcmp ("taskloop", p) == 0)
> @@ -32340,7 +32350,9 @@ cp_parser_omp_clause_if (cp_parser *pars
>             const char *p = NULL;
>             switch (if_modifier)
>               {
> +             case VOID_CST: p = "cancel"; break;
>               case OMP_PARALLEL: p = "parallel"; break;
> +             case OMP_SIMD: p = "simd"; break;
>               case OMP_TASK: p = "task"; break;
>               case OMP_TASKLOOP: p = "taskloop"; break;
>               case OMP_TARGET_DATA: p = "target data"; break;
> @@ -34211,6 +34223,11 @@ cp_parser_omp_all_clauses (cp_parser *pa
>                                                  clauses, token->location);
>           c_name = "inbranch";
>           break;
> +       case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
> +         clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_NONTEMPORAL,
> +                                           clauses);
> +         c_name = "nontemporal";
> +         break;
>         case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
>           clauses = cp_parser_omp_clause_branch (parser,
>                                                  OMP_CLAUSE_NOTINBRANCH,
> @@ -35628,7 +35645,9 @@ cp_omp_split_clauses (location_t loc, en
>         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)      \
>         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)  \
>         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)    \
> -       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
> +       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)     \
> +       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)           \
> +       | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL))
>
>  static tree
>  cp_parser_omp_simd (cp_parser *parser, cp_token *pragma_tok,
> --- gcc/cp/semantics.c.jj       2018-04-30 15:42:59.718594361 +0200
> +++ gcc/cp/semantics.c  2018-05-04 19:46:19.619888534 +0200
> @@ -6613,6 +6613,20 @@ finish_omp_clauses (tree clauses, enum c
>             }
>           break;
>
> +       case OMP_CLAUSE_NONTEMPORAL:
> +         t = OMP_CLAUSE_DECL (c);
> +         if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
> +           {
> +             if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
> +               break;
> +             if (DECL_P (t))
> +               error ("%qD is not a variable in %<nontemporal%> clause", t);
> +             else
> +               error ("%qE is not a variable in %<nontemporal%> clause", t);
> +             remove = true;
> +           }
> +         break;
> +
>         case OMP_CLAUSE_DEPEND:
>           t = OMP_CLAUSE_DECL (c);
>           if (t == NULL_TREE)
> @@ -8540,6 +8554,11 @@ finish_omp_cancel (tree clauses)
>    tree ifc = omp_find_clause (clauses, OMP_CLAUSE_IF);
>    if (ifc != NULL_TREE)
>      {
> +      if (OMP_CLAUSE_IF_MODIFIER (ifc) != ERROR_MARK
> +         && OMP_CLAUSE_IF_MODIFIER (ifc) != VOID_CST)
> +       error_at (OMP_CLAUSE_LOCATION (ifc),
> +                 "expected %<cancel%> %<if%> clause modifier");
> +
>        tree type = TREE_TYPE (OMP_CLAUSE_IF_EXPR (ifc));
>        ifc = fold_build2_loc (OMP_CLAUSE_LOCATION (ifc), NE_EXPR,
>                              boolean_type_node, OMP_CLAUSE_IF_EXPR (ifc),
> --- gcc/cp/pt.c.jj      2018-04-30 14:08:44.386317291 +0200
> +++ gcc/cp/pt.c 2018-05-04 19:47:03.406932925 +0200
> @@ -16015,6 +16015,7 @@ tsubst_omp_clauses (tree clauses, enum c
>         case OMP_CLAUSE_FROM:
>         case OMP_CLAUSE_TO:
>         case OMP_CLAUSE_MAP:
> +       case OMP_CLAUSE_NONTEMPORAL:
>         case OMP_CLAUSE_USE_DEVICE_PTR:
>         case OMP_CLAUSE_IS_DEVICE_PTR:
>           OMP_CLAUSE_DECL (nc)
> --- gcc/testsuite/c-c++-common/gomp/if-1.c.jj   2017-05-04 15:05:48.979663486 +0200
> +++ gcc/testsuite/c-c++-common/gomp/if-1.c      2018-05-04 19:11:05.874353261 +0200
> @@ -14,6 +14,12 @@ foo (int a, int b, int *p, int *q)
>    #pragma omp parallel for simd if (parallel : a)
>    for (i = 0; i < 16; i++)
>      ;
> +  #pragma omp parallel for simd if (simd : a)
> +  for (i = 0; i < 16; i++)
> +    ;
> +  #pragma omp parallel for simd if (simd : a) if (parallel:b)
> +  for (i = 0; i < 16; i++)
> +    ;
>    #pragma omp task if (a)
>      ;
>    #pragma omp task if (task: a)
> @@ -24,16 +30,37 @@ foo (int a, int b, int *p, int *q)
>    #pragma omp taskloop if (taskloop : a)
>    for (i = 0; i < 16; i++)
>      ;
> +  #pragma omp taskloop simd if (a)
> +  for (i = 0; i < 16; i++)
> +    ;
> +  #pragma omp taskloop simd if (taskloop : a)
> +  for (i = 0; i < 16; i++)
> +    ;
> +  #pragma omp taskloop simd if (simd : a)
> +  for (i = 0; i < 16; i++)
> +    ;
> +  #pragma omp taskloop simd if (taskloop:b) if (simd : a)
> +  for (i = 0; i < 16; i++)
> +    ;
>    #pragma omp target if (a)
>      ;
>    #pragma omp target if (target: a)
>      ;
> +  #pragma omp target simd if (a)
> +  for (i = 0; i < 16; i++)
> +    ;
> +  #pragma omp target simd if (simd : a) if (target: b)
> +  for (i = 0; i < 16; i++)
> +    ;
>    #pragma omp target teams distribute parallel for simd if (a)
>    for (i = 0; i < 16; i++)
>      ;
>    #pragma omp target teams distribute parallel for simd if (parallel : a) if (target: b)
>    for (i = 0; i < 16; i++)
>      ;
> +  #pragma omp target teams distribute parallel for simd if (simd : a) if (target: b)
> +  for (i = 0; i < 16; i++)
> +    ;
>    #pragma omp target data if (a) map (p[0:2])
>      ;
>    #pragma omp target data if (target data: a) map (p[0:2])
> @@ -44,4 +71,47 @@ foo (int a, int b, int *p, int *q)
>    #pragma omp target exit data if (target exit data: a) map (from: p[0:2])
>    #pragma omp target update if (a) to (q[0:3])
>    #pragma omp target update if (target update:a) to (q[0:3])
> +  #pragma omp parallel
> +  {
> +    #pragma omp cancel parallel if (a)
> +  }
> + #pragma omp parallel
> +  {
> +    #pragma omp cancel parallel if (cancel:a)
> +  }
> +  #pragma omp for
> +  for (i = 0; i < 16; i++)
> +    {
> +      #pragma omp cancel for if (a)
> +    }
> +  #pragma omp for
> +  for (i = 0; i < 16; i++)
> +    {
> +      #pragma omp cancel for if (cancel: a)
> +    }
> +  #pragma omp sections
> +    {
> +    #pragma omp section
> +      {
> +       #pragma omp cancel sections if (a)
> +      }
> +    }
> +  #pragma omp sections
> +    {
> +    #pragma omp section
> +      {
> +       #pragma omp cancel sections if (cancel: a)
> +      }
> +    }
> +  #pragma omp taskgroup
> +  {
> +    #pragma omp task
> +    {
> +      #pragma omp cancel taskgroup if (a)
> +    }
> +    #pragma omp task
> +    {
> +      #pragma omp cancel taskgroup if (cancel: a)
> +    }
> +  }
>  }
> --- gcc/testsuite/c-c++-common/gomp/if-2.c.jj   2017-05-04 15:05:48.989663358 +0200
> +++ gcc/testsuite/c-c++-common/gomp/if-2.c      2018-05-04 19:16:03.301535402 +0200
> @@ -18,6 +18,8 @@ foo (int a, int b, int *p, int *q, int t
>      ;
>    #pragma omp parallel if (target update:a) /* { dg-error "expected .parallel. .if. clause modifier rather than .target update." } */
>      ;
> +  #pragma omp parallel if (cancel:a) /* { dg-error "expected .parallel. .if. clause modifier rather than .cancel." } */
> +    ;
>    #pragma omp parallel for simd if (target update: a) /* { dg-error "expected .parallel. .if. clause modifier rather than .target update." } */
>    for (i = 0; i < 16; i++)
>      ;
> @@ -27,12 +29,15 @@ foo (int a, int b, int *p, int *q, int t
>      ;
>    #pragma omp task if (parallel: a) /* { dg-error "expected .task. .if. clause modifier rather than .parallel." } */
>      ;
> +  #pragma omp simd if (cancel: a) /* { dg-error "expected .simd. .if. clause modifier rather than .cancel." } */
> +  for (i = 0; i < 16; i++)
> +    ;
>    #pragma omp taskloop if (task : a) /* { dg-error "expected .taskloop. .if. clause modifier rather than .task." } */
>    for (i = 0; i < 16; i++)
>      ;
>    #pragma omp target if (taskloop: a) /* { dg-error "expected .target. .if. clause modifier rather than .taskloop." } */
>      ;
> -  #pragma omp target teams distribute parallel for simd if (target exit data : a) /* { dg-error "expected .parallel. or .target. .if. clause modifier" } */
> +  #pragma omp target teams distribute parallel for simd if (target exit data : a) /* { dg-error "expected .target. .if. clause modifier" } */
>    for (i = 0; i < 16; i++)
>      ;
>    #pragma omp target data if (target: a) map (p[0:2]) /* { dg-error "expected .target data. .if. clause modifier rather than .target." } */
> @@ -40,4 +45,9 @@ foo (int a, int b, int *p, int *q, int t
>    #pragma omp target enter data if (target data: a) map (to: p[0:2]) /* { dg-error "expected .target enter data. .if. clause modifier rather than .target data." } */
>    #pragma omp target exit data if (target enter data: a) map (from: p[0:2]) /* { dg-error "expected .target exit data. .if. clause modifier rather than .target enter data." } */
>    #pragma omp target update if (target exit data:a) to (q[0:3]) /* { dg-error "expected .target update. .if. clause modifier rather than .target exit data." } */
> +  #pragma omp for
> +  for (i = 0; i < 16; i++)
> +    {
> +      #pragma omp cancel for if (target exit data:a) /* { dg-error "expected .cancel. .if. clause modifier" } */
> +    }
>  }
> --- gcc/testsuite/c-c++-common/gomp/if-3.c.jj   2018-05-04 19:55:48.724326116 +0200
> +++ gcc/testsuite/c-c++-common/gomp/if-3.c      2018-05-04 19:56:13.394342506 +0200
> @@ -0,0 +1,13 @@
> +/* { dg-do compile } */
> +/* { dg-additional-options "-O2" } */
> +
> +#define N 1024
> +
> +void
> +foo (int *x, int *y, int *z, int a)
> +{
> +  int i;
> +  #pragma omp simd if (simd: a > 2) aligned (x, y, z : 16)
> +  for (i = 0; i < N; i++)
> +    x[i] = y[i] + z[i];
> +}
> --- gcc/testsuite/c-c++-common/gomp/nontemporal-1.c.jj  2018-05-04 19:53:10.437220971 +0200
> +++ gcc/testsuite/c-c++-common/gomp/nontemporal-1.c     2018-05-04 19:55:43.605322718 +0200
> @@ -0,0 +1,17 @@
> +/* { dg-do compile } */
> +/* { dg-additional-options "-O2" } */
> +
> +#define N 1024
> +int a[N], b[N], c[N], d[N];
> +
> +void
> +foo (void)
> +{
> +  int i;
> +  #pragma omp simd nontemporal (a, b)
> +  for (i = 0; i < N; ++i)
> +    a[i] = b[i] + c[i];
> +  #pragma omp simd nontemporal (d)
> +  for (i = 0; i < N; ++i)
> +    d[i] = 2 * c[i];
> +}
> --- libgomp/testsuite/libgomp.c/cancel-for-2.c.jj       2017-05-04 15:04:53.572372727 +0200
> +++ libgomp/testsuite/libgomp.c/cancel-for-2.c  2018-05-04 18:55:11.627733128 +0200
> @@ -20,7 +20,7 @@ foo (int *x)
>      #pragma omp for
>      for (i = 0; i < 1000; ++i)
>        {
> -       #pragma omp cancel for if (x[1])
> +       #pragma omp cancel for if (cancel: x[1])
>         #pragma omp atomic
>         v++;
>        }
> @@ -34,7 +34,7 @@ foo (int *x)
>      #pragma omp for
>      for (i = 0; i < 1000; ++i)
>        {
> -       #pragma omp cancel for if (x[3])
> +       #pragma omp cancel for if ( cancel : x[3])
>         #pragma omp atomic
>         v += 2;
>        }
> @@ -54,7 +54,7 @@ foo (int *x)
>         #pragma omp cancel for if (x[0])
>         abort ();
>        }
> -    #pragma omp cancel parallel if (omp_get_thread_num () == 2 && x[4])
> +    #pragma omp cancel parallel if (cancel:omp_get_thread_num () == 2 && x[4])
>      #pragma omp for
>      for (i = 0; i < 1000; ++i)
>        {
>
>         Jakub



More information about the Gcc-patches mailing list