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

Jakub Jelinek jakub@redhat.com
Fri May 4 18:38:00 GMT 2018


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?), 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?

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