This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gomp4.1] Initial support for some OpenMP 4.1 construct parsing


Hi!

Here is what I've committed to gomp-4_1-branch, a new branch for OpenMP 4.1
support.  The intent is to develop OpenMP 4.1 support on the branch and
merge to trunk either when OpenMP 4.1 standard is released, or when
sufficiently close to the release, ideally before end of stage1.

I'll probably work on taskloop construct next.

2015-04-29  Jakub Jelinek  <jakub@redhat.com>

gcc/
	* gimple.h (enum gf_mask): Increment GF_OMP_TARGET_KIND_MASK
	to 15 from 7.  Add GF_OMP_TARGET_KIND_ENTER_DATA and
	GF_OMP_TARGET_KIND_EXIT_DATA, renumber GF_OMP_TARGET_KIND_OACC*.
	* tree.h (OMP_ORDERED_CLAUSES, OMP_TARGET_ENTER_DATA_CLAUSES,
	OMP_TARGET_EXIT_DATA_CLAUSES, OMP_CLAUSE_NUM_TASKS_EXPR,
	OMP_CLAUSE_GRAINSIZE_EXPR, OMP_CLAUSE_PRIORITY_EXPR,
	OMP_CLAUSE_ORDERED_EXPR): Define.
	* tree.def (OMP_TASKLOOP, OMP_TARGET_ENTER_DATA,
	OMP_TARGET_EXIT_DATA): New tree codes.
	(OMP_ORDERED): Add second operand - OMP_ORDERED_CLAUSES.  Move
	before OMP_SINGLE, so that OMP_CLAUSES can be used on it too.
	* gimplify.c (gimplify_scan_omp_clauses): Handle
	OMP_CLAUSE_{PRIORITY,GRAINSIZE,NUM_TASKS,NOGROUP,THREADS,SIMD,SIMDLEN}
	clauses.
	(gimplify_adjust_omp_clauses): Likewise.
	(gimplify_omp_target_update): Handle OMP_TARGET_ENTER_DATA
	and OMP_TARGET_EXIT_DATA.
	(gimplify_expr): Likewise.
	* tree.c (omp_clause_num_ops): Change OMP_CLAUSE_ORDERED operand
	count to 1 from 0.  Add entries for
	OMP_CLAUSE_{PRIORITY,GRAINSIZE,NUM_TASKS,NOGROUP,THREADS,SIMD}.
	(omp_clause_code_name): Add names for
	OMP_CLAUSE_{PRIORITY,GRAINSIZE,NUM_TASKS,NOGROUP,THREADS,SIMD}
	clauses.
	(walk_tree_1): Handle
	OMP_CLAUSE_{PRIORITY,GRAINSIZE,NUM_TASKS,NOGROUP,THREADS,SIMD}
	clauses.  Handle OMP_CLAUSE_ORDERED as other 1 operand clauses.
	* tree-nested.c (convert_nonlocal_omp_clauses): Handle
	OMP_CLAUSE_{PRIORITY,GRAINSIZE,NUM_TASKS,NOGROUP,THREADS,SIMD,SIMDLEN}
	clauses.
	(convert_local_omp_clauses): Likewise.
	* gimple-pretty-print.c (dump_gimple_omp_target): Handle
	GF_OMP_TARGET_KIND_ENTER_DATA and GF_OMP_TARGET_KIND_EXIT_DATA.
	* tree-core.h (enum omp_clause_code): Add
	OMP_CLAUSE_{PRIORITY,GRAINSIZE,NUM_TASKS,NOGROUP,THREADS,SIMD}.
	(enum omp_clause_depend_kind): Add OMP_CLAUSE_DEPEND_{SOURCE,SINK}.
	* omp-low.c (scan_sharing_clauses): Handle
	OMP_CLAUSE_{PRIORITY,GRAINSIZE,NUM_TASKS,NOGROUP,THREADS,SIMD,SIMDLEN}
	clauses.
	(check_omp_nesting_restrictions): Handle
	GF_OMP_TARGET_KIND_ENTER_DATA and GF_OMP_TARGET_KIND_EXIT_DATA.
	Formatting fixes.
	(expand_omp_target): Handle GF_OMP_TARGET_KIND_ENTER_DATA and
	GF_OMP_TARGET_KIND_EXIT_DATA.
	(build_omp_regions_1, make_gimple_omp_edges): Likewise.
	(lower_omp_target): Likewise.  Don't assert is_gimple_omp_oacc
	for certain OpenMP 4.1 map kinds + modifiers.
	* tree-pretty-print.c (dump_omp_clause): Handle
	OMP_CLAUSE_ORDERED_EXPR on OMP_CLAUSE_ORDERED.  Handle
	OMP_CLAUSE_DEPEND_SOURCE on OMP_CLAUSE_DEPEND.  Adjust printing
	OpenMP 4.1 new map kinds and modifiers.  Handle
	OMP_CLAUSE_{PRIORITY,GRAINSIZE,NUM_TASKS,NOGROUP,THREADS,SIMD}
	clauses.
	(dump_generic_node): Handle OMP_{TASKLOOP,TARGET_{ENTER,EXIT}_DATA}.
	Dump OMP_ORDERED_CLAUSES for OMP_ORDERED.
gcc/c-family/
	* c-omp.c (c_finish_omp_ordered): Add CLAUSES argument, adjust
	for building 2 operand tree instead of single operand tree.
	(c_omp_split_clauses): Add taskloop simd splitting support.
	* c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_TASKLOOP.
	(enum pragma_omp_clause): Add
	PRAGMA_OMP_CLAUSE_{PRIORITY,GRAINSIZE,NUM_TASKS,NOGROUP,THREADS,SIMD}.
	* c-common.h (enum c_omp_clause_split): Add C_OMP_CLAUSE_SPLIT_TASKLOOP
	as alias to C_OMP_CLAUSE_SPLIT_FOR.
	(c_finish_omp_ordered): Adjust prototype for CLAUSES argument addition.
gcc/c/
	* c-typeck.c (c_finish_omp_clauses): Allow NULL OMP_CLAUSE_DECL
	for OMP_CLAUSE_DEPEND_SOURCE.  Diagnose simdlen > safelen.  Handle
	OMP_CLAUSE_{PRIORITY,GRAINSIZE,NUM_TASKS,NOGROUP,THREADS,SIMD}
	clauses.
	* c-parser.c (c_parser_pragma): Handle PRAGMA_OMP_ORDERED.
	(c_parser_omp_clause_name): Handle grainsize, nogroup, num_tasks,
	priority, simd and threads clauses.
	(c_parser_omp_clause_num_tasks, c_parser_omp_clause_grainsize,
	c_parser_omp_clause_priority): New functions.
	(c_parser_omp_clause_ordered): Handle parsing of optional argument.
	(c_parser_omp_clause_nogroup, c_parser_omp_clause_orderedkind):
	New functions.
	(c_parser_omp_clause_depend): Handle parsing of depend(source)
	and partially handle depend(sink:vec).
	(c_parser_omp_clause_map): Parse optional always map type modifier.
	Handle parsing of delete map kind.
	(c_parser_omp_all_clauses): Handle
	PRAGMA_OMP_CLAUSE_{GRAINSIZE,NUM_TASKS,PRIORITY,NOGROUP,THREADS,SIMD}.
	(OMP_SIMD_CLAUSE_MASK): Add simdlen clause.
	(OMP_FOR_CLAUSE_MASK): Add linear clause.
	(OMP_ORDERED_CLAUSE_MASK, OMP_ORDERED_DEPEND_CLAUSE_MASK): Define.
	(c_parser_omp_ordered): Handle parsing of the clauses, and if depend
	clause is present, parse it as standalone directive.  Remove LOC
	argument, add CONTEXT argument.
	(OMP_TASK_CLAUSE_MASK): Add priority clause.
	(c_parser_omp_target_data): Diagnose if no map clauses are present.
	(OMP_TARGET_ENTER_DATA_CLAUSE_MASK): Define.
	(c_parser_omp_target_enter_data): New function.
	OMP_TARGET_EXIT_DATA_CLAUSE_MASK): Define.
	(c_parser_omp_target_exit_data): New function.
	(OMP_TARGET_CLAUSE_MASK): Add nowait and depend clauses.
	(c_parser_omp_target): Handle #pragma omp target {enter,exit} data.
	(OMP_TASKLOOP_CLAUSE_MASK): Define.
	(c_parser_omp_taskloop): New function.
	(c_parser_omp_construct): Don't handle PRAGMA_OMP_ORDERED here.
	Handle PRAGMA_OMP_TASKLOOP.
gcc/cp/
	* parser.c (cp_parser_omp_clause_ordered): Clear
	OMP_CLAUSE_ORDERED_EXPR.
	(cp_parser_omp_ordered): Pass NULL_TREE as clauses
	to c_finish_omp_ordered.
gcc/fortran/
	* trans-openmp.c (gfc_trans_omp_clauses): Clear
	OMP_CLAUSE_ORDERED_EXPR.
	(gfc_trans_omp_ordered): Adjust for OMP_ORDERED change from 1
	operand to 2 operands.
gcc/testsuite/
	* c-c++-common/gomp/cancel-1.c (f2): Add map clause to all
	#pragma omp target data directives.
	* c-c++-common/gomp/nesting-warn-1.c (f_omp_target): Likewise.
	* c-c++-common/gomp/nesting-1.c (f_omp_parallel, f_omp_target,
	f_omp_target_data): Likewise.
libgomp/
	* omp.h.in (omp_get_max_task_priority): New prototype.
	* omp_lib.h.in (omp_get_max_task_priority): New extern.
	* omp_lib.f90.in (omp_get_max_task_priority): New interface.
	* fortran.c (omp_get_max_task_priority_): New function.
	(omp_get_max_task_priority): Add ialias_redirect.
	* libgomp.map (OMP_4.1): Export omp_get_max_task_priority
	and omp_get_max_task_priority_.
	* env.c (gomp_max_task_priority_var): New variable.
	(handle_omp_display_env): Print OMP_MAX_TASK_PRIORITY.
	(initialize_env): Handle OMP_MAX_TASK_PRIORITY env var.
	(omp_get_max_task_priority): New function.

--- libgomp/omp.h.in.jj	2015-04-29 10:58:01.195752796 +0200
+++ libgomp/omp.h.in	2015-04-29 11:03:04.609991598 +0200
@@ -120,6 +120,7 @@ extern int omp_get_num_teams (void) __GO
 extern int omp_get_team_num (void) __GOMP_NOTHROW;
 
 extern int omp_is_initial_device (void) __GOMP_NOTHROW;
+extern int omp_get_max_task_priority (void) __GOMP_NOTHROW;
 
 #ifdef __cplusplus
 }
--- libgomp/omp_lib.h.in.jj	2015-04-29 10:58:01.204752655 +0200
+++ libgomp/omp_lib.h.in	2015-04-29 11:03:04.609991598 +0200
@@ -96,3 +96,6 @@
 
       external omp_is_initial_device
       logical(4) omp_is_initial_device
+
+      external omp_get_max_task_priority
+      integer(4) omp_get_max_task_priority
--- libgomp/fortran.c.jj	2015-04-29 10:58:01.205752639 +0200
+++ libgomp/fortran.c	2015-04-29 11:03:04.610991582 +0200
@@ -74,6 +74,7 @@ ialias_redirect (omp_get_num_devices)
 ialias_redirect (omp_get_num_teams)
 ialias_redirect (omp_get_team_num)
 ialias_redirect (omp_is_initial_device)
+ialias_redirect (omp_get_max_task_priority)
 #endif
 
 #ifndef LIBGOMP_GNU_SYMBOL_VERSIONING
@@ -493,3 +494,9 @@ omp_is_initial_device_ (void)
 {
   return omp_is_initial_device ();
 }
+
+int32_t
+omp_get_max_task_priority_ (void)
+{
+  return omp_get_max_task_priority ();
+}
--- libgomp/libgomp.map.jj	2015-04-29 10:58:01.205752639 +0200
+++ libgomp/libgomp.map	2015-04-29 11:03:04.610991582 +0200
@@ -134,6 +134,12 @@ OMP_4.0 {
 	omp_is_initial_device_;
 } OMP_3.1;
 
+OMP_4.1 {
+  global:
+	omp_get_max_task_priority;
+	omp_get_max_task_priority_;
+} OMP_4.0;
+
 GOMP_1.0 {
   global:
 	GOMP_atomic_end;
--- libgomp/omp_lib.f90.in.jj	2015-04-29 10:58:01.194752811 +0200
+++ libgomp/omp_lib.f90.in	2015-04-29 11:03:04.610991582 +0200
@@ -337,4 +337,10 @@
           end function omp_is_initial_device
         end interface
 
+        interface
+          function omp_get_max_task_priority ()
+            integer (4) :: omp_get_max_task_priority
+          end function omp_get_max_task_priority
+        end interface
+
       end module omp_lib
--- libgomp/env.c.jj	2015-04-29 10:58:01.206752623 +0200
+++ libgomp/env.c	2015-04-29 11:03:04.611991566 +0200
@@ -68,6 +68,7 @@ struct gomp_task_icv gomp_global_icv = {
 
 unsigned long gomp_max_active_levels_var = INT_MAX;
 bool gomp_cancel_var = false;
+int gomp_max_task_priority_var = 0;
 #ifndef HAVE_SYNC_BUILTINS
 gomp_mutex_t gomp_managed_threads_lock;
 #endif
@@ -1157,6 +1158,8 @@ handle_omp_display_env (unsigned long st
 	   gomp_cancel_var ? "TRUE" : "FALSE");
   fprintf (stderr, "  OMP_DEFAULT_DEVICE = '%d'\n",
 	   gomp_global_icv.default_device_var);
+  fprintf (stderr, "  OMP_MAX_TASK_PRIORITY = '%d'\n",
+	   gomp_max_task_priority_var);
 
   if (verbose)
     {
@@ -1189,6 +1192,7 @@ initialize_env (void)
   parse_boolean ("OMP_NESTED", &gomp_global_icv.nest_var);
   parse_boolean ("OMP_CANCELLATION", &gomp_cancel_var);
   parse_int ("OMP_DEFAULT_DEVICE", &gomp_global_icv.default_device_var, true);
+  parse_int ("OMP_MAX_TASK_PRIORITY", &gomp_max_task_priority_var, true);
   parse_unsigned_long ("OMP_MAX_ACTIVE_LEVELS", &gomp_max_active_levels_var,
 		       true);
   if (parse_unsigned_long ("OMP_THREAD_LIMIT", &thread_limit_var, false))
@@ -1402,6 +1406,12 @@ omp_get_cancellation (void)
   return gomp_cancel_var;
 }
 
+int
+omp_get_max_task_priority (void)
+{
+  return gomp_max_task_priority_var;
+}
+
 omp_proc_bind_t
 omp_get_proc_bind (void)
 {
@@ -1469,3 +1479,4 @@ ialias (omp_get_num_devices)
 ialias (omp_get_num_teams)
 ialias (omp_get_team_num)
 ialias (omp_is_initial_device)
+ialias (omp_get_max_task_priority)
--- gcc/gimple.h.jj	2015-04-29 10:58:01.665745421 +0200
+++ gcc/gimple.h	2015-04-29 11:03:04.612991551 +0200
@@ -100,15 +100,17 @@ enum gf_mask {
     GF_OMP_FOR_KIND_CILKSIMD	= GF_OMP_FOR_SIMD | 1,
     GF_OMP_FOR_COMBINED		= 1 << 3,
     GF_OMP_FOR_COMBINED_INTO	= 1 << 4,
-    GF_OMP_TARGET_KIND_MASK	= (1 << 3) - 1,
+    GF_OMP_TARGET_KIND_MASK	= (1 << 4) - 1,
     GF_OMP_TARGET_KIND_REGION	= 0,
     GF_OMP_TARGET_KIND_DATA	= 1,
     GF_OMP_TARGET_KIND_UPDATE	= 2,
-    GF_OMP_TARGET_KIND_OACC_PARALLEL = 3,
-    GF_OMP_TARGET_KIND_OACC_KERNELS = 4,
-    GF_OMP_TARGET_KIND_OACC_DATA = 5,
-    GF_OMP_TARGET_KIND_OACC_UPDATE = 6,
-    GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA = 7,
+    GF_OMP_TARGET_KIND_ENTER_DATA = 3,
+    GF_OMP_TARGET_KIND_EXIT_DATA = 4,
+    GF_OMP_TARGET_KIND_OACC_PARALLEL = 5,
+    GF_OMP_TARGET_KIND_OACC_KERNELS = 6,
+    GF_OMP_TARGET_KIND_OACC_DATA = 7,
+    GF_OMP_TARGET_KIND_OACC_UPDATE = 8,
+    GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA = 9,
 
     /* True on an GIMPLE_OMP_RETURN statement if the return does not require
        a thread synchronization via some sort of barrier.  The exact barrier
--- gcc/cp/parser.c.jj	2015-04-29 10:58:01.661745483 +0200
+++ gcc/cp/parser.c	2015-04-29 11:03:04.621991409 +0200
@@ -28407,6 +28407,7 @@ cp_parser_omp_clause_ordered (cp_parser
 			     "ordered", location);
 
   c = build_omp_clause (location, OMP_CLAUSE_ORDERED);
+  OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
   OMP_CLAUSE_CHAIN (c) = list;
   return c;
 }
@@ -30796,7 +30797,8 @@ cp_parser_omp_ordered (cp_parser *parser
 {
   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   cp_parser_require_pragma_eol (parser, pragma_tok);
-  return c_finish_omp_ordered (loc, cp_parser_omp_structured_block (parser));
+  return c_finish_omp_ordered (loc, NULL_TREE,
+			       cp_parser_omp_structured_block (parser));
 }
 
 /* OpenMP 2.5:
--- gcc/tree.h.jj	2015-04-29 10:58:01.659745515 +0200
+++ gcc/tree.h	2015-04-29 11:03:04.623991378 +0200
@@ -1268,6 +1268,7 @@ extern void protected_set_expr_location
 #define OMP_TASKGROUP_BODY(NODE)   TREE_OPERAND (OMP_TASKGROUP_CHECK (NODE), 0)
 
 #define OMP_ORDERED_BODY(NODE)	   TREE_OPERAND (OMP_ORDERED_CHECK (NODE), 0)
+#define OMP_ORDERED_CLAUSES(NODE)  TREE_OPERAND (OMP_ORDERED_CHECK (NODE), 1)
 
 #define OMP_CRITICAL_BODY(NODE)    TREE_OPERAND (OMP_CRITICAL_CHECK (NODE), 0)
 #define OMP_CRITICAL_NAME(NODE)    TREE_OPERAND (OMP_CRITICAL_CHECK (NODE), 1)
@@ -1286,6 +1287,12 @@ extern void protected_set_expr_location
 #define OMP_TARGET_UPDATE_CLAUSES(NODE)\
   TREE_OPERAND (OMP_TARGET_UPDATE_CHECK (NODE), 0)
 
+#define OMP_TARGET_ENTER_DATA_CLAUSES(NODE)\
+  TREE_OPERAND (OMP_TARGET_ENTER_DATA_CHECK (NODE), 0)
+
+#define OMP_TARGET_EXIT_DATA_CLAUSES(NODE)\
+  TREE_OPERAND (OMP_TARGET_EXIT_DATA_CHECK (NODE), 0)
+
 #define OMP_CLAUSE_SIZE(NODE)						\
   OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (OMP_CLAUSE_CHECK (NODE),	\
 					      OMP_CLAUSE_FROM,		\
@@ -1356,6 +1363,14 @@ extern void protected_set_expr_location
   OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_NUM_THREADS),0)
 #define OMP_CLAUSE_SCHEDULE_CHUNK_EXPR(NODE) \
   OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_SCHEDULE), 0)
+#define OMP_CLAUSE_NUM_TASKS_EXPR(NODE) \
+  OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_NUM_TASKS),0)
+
+#define OMP_CLAUSE_GRAINSIZE_EXPR(NODE) \
+  OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_GRAINSIZE),0)
+
+#define OMP_CLAUSE_PRIORITY_EXPR(NODE) \
+  OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_PRIORITY),0)
 
 /* OpenACC clause expressions  */
 #define OMP_CLAUSE_GANG_EXPR(NODE) \
@@ -1411,6 +1426,9 @@ extern void protected_set_expr_location
 #define OMP_CLAUSE_COLLAPSE_COUNT(NODE) \
   OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_COLLAPSE), 2)
 
+#define OMP_CLAUSE_ORDERED_EXPR(NODE) \
+  OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_ORDERED), 0)
+
 #define OMP_CLAUSE_REDUCTION_CODE(NODE)	\
   (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION)->omp_clause.subcode.reduction_code)
 #define OMP_CLAUSE_REDUCTION_INIT(NODE) \
--- gcc/tree.def.jj	2015-04-29 10:58:01.663745452 +0200
+++ gcc/tree.def	2015-04-29 11:34:18.293302684 +0200
@@ -1106,6 +1106,10 @@ DEFTREECODE (CILK_FOR, "cilk_for", tcc_s
    Operands like for OMP_FOR.  */
 DEFTREECODE (OMP_DISTRIBUTE, "omp_distribute", tcc_statement, 6)
 
+/* OpenMP - #pragma omp taskloop [clause1 ... clauseN]
+   Operands like for OMP_FOR.  */
+DEFTREECODE (OMP_TASKLOOP, "omp_taskloop", tcc_statement, 6)
+
 /* OpenMP - #pragma acc loop [clause1 ... clauseN]
    Operands like for OMP_FOR.  */
 DEFTREECODE (OACC_LOOP, "oacc_loop", tcc_statement, 6)
@@ -1130,6 +1134,11 @@ DEFTREECODE (OMP_TARGET, "omp_target", t
    Operand 1: OMP_SECTIONS_CLAUSES: List of clauses.  */
 DEFTREECODE (OMP_SECTIONS, "omp_sections", tcc_statement, 2)
 
+/* OpenMP - #pragma omp ordered
+   Operand 0: OMP_ORDERED_BODY: Master section body.
+   Operand 1: OMP_ORDERED_CLAUSES: List of clauses.  */
+DEFTREECODE (OMP_ORDERED, "omp_ordered", tcc_statement, 2)
+
 /* OpenMP - #pragma omp single
    Operand 0: OMP_SINGLE_BODY: Single section body.
    Operand 1: OMP_SINGLE_CLAUSES: List of clauses.  */
@@ -1147,10 +1156,6 @@ DEFTREECODE (OMP_MASTER, "omp_master", t
    Operand 0: OMP_TASKGROUP_BODY: Taskgroup body.  */
 DEFTREECODE (OMP_TASKGROUP, "omp_taskgroup", tcc_statement, 1)
 
-/* OpenMP - #pragma omp ordered
-   Operand 0: OMP_ORDERED_BODY: Master section body.  */
-DEFTREECODE (OMP_ORDERED, "omp_ordered", tcc_statement, 1)
-
 /* OpenMP - #pragma omp critical [name]
    Operand 0: OMP_CRITICAL_BODY: Critical section body.
    Operand 1: OMP_CRITICAL_NAME: Identifier for critical section.  */
@@ -1181,6 +1186,14 @@ DEFTREECODE (OACC_UPDATE, "oacc_update",
    Operand 0: OMP_TARGET_UPDATE_CLAUSES: List of clauses.  */
 DEFTREECODE (OMP_TARGET_UPDATE, "omp_target_update", tcc_statement, 1)
 
+/* OpenMP - #pragma omp target enter data [clause1 ... clauseN]
+   Operand 0: OMP_TARGET_ENTER_DATA_CLAUSES: List of clauses.  */
+DEFTREECODE (OMP_TARGET_ENTER_DATA, "omp_target_enter_data", tcc_statement, 1)
+
+/* OpenMP - #pragma omp target exit data [clause1 ... clauseN]
+   Operand 0: OMP_TARGET_EXIT_DATA_CLAUSES: List of clauses.  */
+DEFTREECODE (OMP_TARGET_EXIT_DATA, "omp_target_exit_data", tcc_statement, 1)
+
 /* OMP_ATOMIC through OMP_ATOMIC_CAPTURE_NEW must be consecutive,
    or OMP_ATOMIC_SEQ_CST needs adjusting.  */
 
--- gcc/testsuite/c-c++-common/gomp/cancel-1.c.jj	2015-04-29 10:58:01.492748135 +0200
+++ gcc/testsuite/c-c++-common/gomp/cancel-1.c	2015-04-29 11:03:04.624991362 +0200
@@ -17,7 +17,7 @@ f1 (void)
 void
 f2 (void)
 {
-  int i;
+  int i, j = 0;
   #pragma omp parallel
   {
     #pragma omp cancel parallel
@@ -132,7 +132,7 @@ f2 (void)
 	#pragma omp cancellation point taskgroup/* { dg-error "not closely nested inside" } */
       }
     }
-    #pragma omp target data
+    #pragma omp target data map(j)
     {
       #pragma omp cancel parallel		/* { dg-error "not closely nested inside" } */
       #pragma omp cancel for			/* { dg-error "not closely nested inside" } */
@@ -155,7 +155,7 @@ f2 (void)
       #pragma omp cancellation point taskgroup	/* { dg-error "not closely nested inside" } */
     }
   }
-  #pragma omp target data
+  #pragma omp target data map(j)
   {
     #pragma omp cancel parallel			/* { dg-error "not closely nested inside" } */
     #pragma omp cancel for			/* { dg-error "not closely nested inside" } */
@@ -214,7 +214,7 @@ f2 (void)
     }
   #pragma omp for
   for (i = 0; i < 10; i++)
-    #pragma omp target data
+    #pragma omp target data map(j)
     {
       #pragma omp cancel parallel		/* { dg-error "not closely nested inside" } */
       #pragma omp cancel for			/* { dg-error "not closely nested inside" } */
@@ -241,7 +241,7 @@ f2 (void)
   #pragma omp for ordered
   for (i = 0; i < 10; i++)
     #pragma omp ordered
-      #pragma omp target data
+      #pragma omp target data map(j)
       {
 	#pragma omp cancel parallel		/* { dg-error "not closely nested inside" } */
 	#pragma omp cancel for			/* { dg-error "not closely nested inside" } */
@@ -292,7 +292,7 @@ f2 (void)
   }
   #pragma omp sections
   {
-    #pragma omp target data
+    #pragma omp target data map(j)
     {
       #pragma omp cancel parallel		/* { dg-error "not closely nested inside" } */
       #pragma omp cancel for			/* { dg-error "not closely nested inside" } */
@@ -304,7 +304,7 @@ f2 (void)
       #pragma omp cancellation point taskgroup	/* { dg-error "not closely nested inside" } */
     }
     #pragma omp section
-    #pragma omp target data
+    #pragma omp target data map(j)
     {
       #pragma omp cancel parallel		/* { dg-error "not closely nested inside" } */
       #pragma omp cancel for			/* { dg-error "not closely nested inside" } */
--- gcc/testsuite/c-c++-common/gomp/nesting-warn-1.c.jj	2015-04-29 10:58:01.491748151 +0200
+++ gcc/testsuite/c-c++-common/gomp/nesting-warn-1.c	2015-04-29 11:03:04.625991347 +0200
@@ -7,7 +7,7 @@ f_omp_target (void)
   {
 #pragma omp target /* { dg-warning "target construct inside of target region" } */
     ;
-#pragma omp target data /* { dg-warning "target data construct inside of target region" } */
+#pragma omp target data map(i) /* { dg-warning "target data construct inside of target region" } */
     ;
 #pragma omp target update to(i) /* { dg-warning "target update construct inside of target region" } */
 
@@ -15,7 +15,7 @@ f_omp_target (void)
     {
 #pragma omp target /* { dg-warning "target construct inside of target region" } */
       ;
-#pragma omp target data /* { dg-warning "target data construct inside of target region" } */
+#pragma omp target data map(i) /* { dg-warning "target data construct inside of target region" } */
       ;
 #pragma omp target update to(i) /* { dg-warning "target update construct inside of target region" } */
     }
--- gcc/testsuite/c-c++-common/gomp/nesting-1.c.jj	2015-04-29 10:58:01.491748151 +0200
+++ gcc/testsuite/c-c++-common/gomp/nesting-1.c	2015-04-29 11:03:04.625991347 +0200
@@ -11,12 +11,12 @@ f_omp_parallel (void)
 #pragma omp target
     ;
 
-#pragma omp target data
+#pragma omp target data map(i)
     ;
 
 #pragma omp target update to(i)
 
-#pragma omp target data
+#pragma omp target data map(i)
     {
 #pragma omp parallel
       ;
@@ -24,7 +24,7 @@ f_omp_parallel (void)
 #pragma omp target
       ;
 
-#pragma omp target data
+#pragma omp target data map(i)
       ;
 
 #pragma omp target update to(i)
@@ -45,7 +45,7 @@ f_omp_target (void)
 void
 f_omp_target_data (void)
 {
-#pragma omp target data
+#pragma omp target data map(i)
   {
 #pragma omp parallel
     ;
@@ -53,12 +53,12 @@ f_omp_target_data (void)
 #pragma omp target
     ;
 
-#pragma omp target data
+#pragma omp target data map(i)
     ;
 
 #pragma omp target update to(i)
 
-#pragma omp target data
+#pragma omp target data map(i)
     {
 #pragma omp parallel
       ;
@@ -66,7 +66,7 @@ f_omp_target_data (void)
 #pragma omp target
       ;
 
-#pragma omp target data
+#pragma omp target data map(i)
       ;
 
 #pragma omp target update to(i)
--- gcc/gimplify.c.jj	2015-04-29 10:59:42.520162806 +0200
+++ gcc/gimplify.c	2015-04-29 11:03:04.628991299 +0200
@@ -6336,6 +6336,9 @@ gimplify_scan_omp_clauses (tree *list_p,
 	case OMP_CLAUSE_THREAD_LIMIT:
 	case OMP_CLAUSE_DIST_SCHEDULE:
 	case OMP_CLAUSE_DEVICE:
+	case OMP_CLAUSE_PRIORITY:
+	case OMP_CLAUSE_GRAINSIZE:
+	case OMP_CLAUSE_NUM_TASKS:
 	case OMP_CLAUSE__CILK_FOR_COUNT_:
 	case OMP_CLAUSE_ASYNC:
 	case OMP_CLAUSE_WAIT:
@@ -6369,6 +6372,10 @@ gimplify_scan_omp_clauses (tree *list_p,
 	case OMP_CLAUSE_MERGEABLE:
 	case OMP_CLAUSE_PROC_BIND:
 	case OMP_CLAUSE_SAFELEN:
+	case OMP_CLAUSE_SIMDLEN:
+	case OMP_CLAUSE_NOGROUP:
+	case OMP_CLAUSE_THREADS:
+	case OMP_CLAUSE_SIMD:
 	  break;
 
 	case OMP_CLAUSE_ALIGNED:
@@ -6739,7 +6746,14 @@ gimplify_adjust_omp_clauses (gimple_seq
 	case OMP_CLAUSE_MERGEABLE:
 	case OMP_CLAUSE_PROC_BIND:
 	case OMP_CLAUSE_SAFELEN:
+	case OMP_CLAUSE_SIMDLEN:
 	case OMP_CLAUSE_DEPEND:
+	case OMP_CLAUSE_PRIORITY:
+	case OMP_CLAUSE_GRAINSIZE:
+	case OMP_CLAUSE_NUM_TASKS:
+	case OMP_CLAUSE_NOGROUP:
+	case OMP_CLAUSE_THREADS:
+	case OMP_CLAUSE_SIMD:
 	case OMP_CLAUSE__CILK_FOR_COUNT_:
 	case OMP_CLAUSE_ASYNC:
 	case OMP_CLAUSE_WAIT:
@@ -7433,6 +7447,14 @@ gimplify_omp_target_update (tree *expr_p
       clauses = OMP_TARGET_UPDATE_CLAUSES (expr);
       kind = GF_OMP_TARGET_KIND_UPDATE;
       break;
+    case OMP_TARGET_ENTER_DATA:
+      clauses = OMP_TARGET_ENTER_DATA_CLAUSES (expr);
+      kind = GF_OMP_TARGET_KIND_ENTER_DATA;
+      break;
+    case OMP_TARGET_EXIT_DATA:
+      clauses = OMP_TARGET_EXIT_DATA_CLAUSES (expr);
+      kind = GF_OMP_TARGET_KIND_EXIT_DATA;
+      break;
     default:
       gcc_unreachable ();
     }
@@ -8426,6 +8448,8 @@ gimplify_expr (tree *expr_p, gimple_seq
 	case OACC_EXIT_DATA:
 	case OACC_UPDATE:
 	case OMP_TARGET_UPDATE:
+	case OMP_TARGET_ENTER_DATA:
+	case OMP_TARGET_EXIT_DATA:
 	  gimplify_omp_target_update (expr_p, pre_p);
 	  ret = GS_ALL_DONE;
 	  break;
--- gcc/tree.c.jj	2015-04-29 10:59:22.836471684 +0200
+++ gcc/tree.c	2015-04-29 11:03:04.631991252 +0200
@@ -342,7 +342,7 @@ unsigned const char omp_clause_num_ops[]
   1, /* OMP_CLAUSE_NUM_THREADS  */
   1, /* OMP_CLAUSE_SCHEDULE  */
   0, /* OMP_CLAUSE_NOWAIT  */
-  0, /* OMP_CLAUSE_ORDERED  */
+  1, /* OMP_CLAUSE_ORDERED  */
   0, /* OMP_CLAUSE_DEFAULT  */
   3, /* OMP_CLAUSE_COLLAPSE  */
   0, /* OMP_CLAUSE_UNTIED   */
@@ -361,6 +361,12 @@ unsigned const char omp_clause_num_ops[]
   0, /* OMP_CLAUSE_PARALLEL  */
   0, /* OMP_CLAUSE_SECTIONS  */
   0, /* OMP_CLAUSE_TASKGROUP  */
+  1, /* OMP_CLAUSE_PRIORITY  */
+  1, /* OMP_CLAUSE_GRAINSIZE  */
+  1, /* OMP_CLAUSE_NUM_TASKS  */
+  0, /* OMP_CLAUSE_NOGROUP  */
+  0, /* OMP_CLAUSE_THREADS  */
+  0, /* OMP_CLAUSE_SIMD  */
   1, /* OMP_CLAUSE__SIMDUID_  */
   1, /* OMP_CLAUSE__CILK_FOR_COUNT_  */
   0, /* OMP_CLAUSE_INDEPENDENT  */
@@ -420,6 +426,12 @@ const char * const omp_clause_code_name[
   "parallel",
   "sections",
   "taskgroup",
+  "priority",
+  "grainsize",
+  "num_tasks",
+  "nogroup",
+  "threads",
+  "simd",
   "_simduid_",
   "_Cilk_for_count_",
   "independent",
@@ -11234,6 +11246,10 @@ walk_tree_1 (tree *tp, walk_tree_fn func
 	case OMP_CLAUSE_DIST_SCHEDULE:
 	case OMP_CLAUSE_SAFELEN:
 	case OMP_CLAUSE_SIMDLEN:
+	case OMP_CLAUSE_ORDERED:
+	case OMP_CLAUSE_PRIORITY:
+	case OMP_CLAUSE_GRAINSIZE:
+	case OMP_CLAUSE_NUM_TASKS:
 	case OMP_CLAUSE__LOOPTEMP_:
 	case OMP_CLAUSE__SIMDUID_:
 	case OMP_CLAUSE__CILK_FOR_COUNT_:
@@ -11242,7 +11258,6 @@ walk_tree_1 (tree *tp, walk_tree_fn func
 
 	case OMP_CLAUSE_INDEPENDENT:
 	case OMP_CLAUSE_NOWAIT:
-	case OMP_CLAUSE_ORDERED:
 	case OMP_CLAUSE_DEFAULT:
 	case OMP_CLAUSE_UNTIED:
 	case OMP_CLAUSE_MERGEABLE:
@@ -11253,6 +11268,9 @@ walk_tree_1 (tree *tp, walk_tree_fn func
 	case OMP_CLAUSE_PARALLEL:
 	case OMP_CLAUSE_SECTIONS:
 	case OMP_CLAUSE_TASKGROUP:
+	case OMP_CLAUSE_NOGROUP:
+	case OMP_CLAUSE_THREADS:
+	case OMP_CLAUSE_SIMD:
 	case OMP_CLAUSE_AUTO:
 	case OMP_CLAUSE_SEQ:
 	  WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
--- gcc/tree-nested.c.jj	2015-04-29 10:58:01.664745436 +0200
+++ gcc/tree-nested.c	2015-04-29 11:03:04.632991237 +0200
@@ -1145,6 +1145,10 @@ convert_nonlocal_omp_clauses (tree *pcla
 	case OMP_CLAUSE_NUM_TEAMS:
 	case OMP_CLAUSE_THREAD_LIMIT:
 	case OMP_CLAUSE_SAFELEN:
+	case OMP_CLAUSE_SIMDLEN:
+	case OMP_CLAUSE_PRIORITY:
+	case OMP_CLAUSE_GRAINSIZE:
+	case OMP_CLAUSE_NUM_TASKS:
 	case OMP_CLAUSE__CILK_FOR_COUNT_:
 	  wi->val_only = true;
 	  wi->is_lhs = false;
@@ -1209,6 +1213,9 @@ convert_nonlocal_omp_clauses (tree *pcla
 	case OMP_CLAUSE_UNTIED:
 	case OMP_CLAUSE_MERGEABLE:
 	case OMP_CLAUSE_PROC_BIND:
+	case OMP_CLAUSE_NOGROUP:
+	case OMP_CLAUSE_THREADS:
+	case OMP_CLAUSE_SIMD:
 	  break;
 
 	default:
@@ -1778,6 +1785,10 @@ convert_local_omp_clauses (tree *pclause
 	case OMP_CLAUSE_NUM_TEAMS:
 	case OMP_CLAUSE_THREAD_LIMIT:
 	case OMP_CLAUSE_SAFELEN:
+	case OMP_CLAUSE_SIMDLEN:
+	case OMP_CLAUSE_PRIORITY:
+	case OMP_CLAUSE_GRAINSIZE:
+	case OMP_CLAUSE_NUM_TASKS:
 	case OMP_CLAUSE__CILK_FOR_COUNT_:
 	  wi->val_only = true;
 	  wi->is_lhs = false;
@@ -1847,6 +1858,9 @@ convert_local_omp_clauses (tree *pclause
 	case OMP_CLAUSE_UNTIED:
 	case OMP_CLAUSE_MERGEABLE:
 	case OMP_CLAUSE_PROC_BIND:
+	case OMP_CLAUSE_NOGROUP:
+	case OMP_CLAUSE_THREADS:
+	case OMP_CLAUSE_SIMD:
 	  break;
 
 	default:
--- gcc/gimple-pretty-print.c.jj	2015-04-29 10:58:01.663745452 +0200
+++ gcc/gimple-pretty-print.c	2015-04-29 11:03:04.632991237 +0200
@@ -1350,6 +1350,12 @@ dump_gimple_omp_target (pretty_printer *
     case GF_OMP_TARGET_KIND_UPDATE:
       kind = " update";
       break;
+    case GF_OMP_TARGET_KIND_ENTER_DATA:
+      kind = " enter data";
+      break;
+    case GF_OMP_TARGET_KIND_EXIT_DATA:
+      kind = " exit data";
+      break;
     case GF_OMP_TARGET_KIND_OACC_KERNELS:
       kind = " oacc_kernels";
       break;
--- gcc/c/c-typeck.c.jj	2015-04-29 10:59:21.436493652 +0200
+++ gcc/c/c-typeck.c	2015-04-29 11:03:04.636991174 +0200
@@ -12053,6 +12053,7 @@ c_finish_omp_clauses (tree clauses)
   bitmap_head generic_head, firstprivate_head, lastprivate_head;
   bitmap_head aligned_head;
   tree c, t, *pc;
+  tree simdlen = NULL_TREE, safelen = NULL_TREE;
   bool branch_seen = false;
   bool copyprivate_seen = false;
   tree *nowait_clause = NULL;
@@ -12345,6 +12346,12 @@ c_finish_omp_clauses (tree clauses)
 
 	case OMP_CLAUSE_DEPEND:
 	  t = OMP_CLAUSE_DECL (c);
+	  if (t == NULL_TREE)
+	    {
+	      gcc_assert (OMP_CLAUSE_DEPEND_KIND (c)
+			  == OMP_CLAUSE_DEPEND_SOURCE);
+	      break;
+	    }
 	  if (TREE_CODE (t) == TREE_LIST)
 	    {
 	      if (handle_omp_array_sections (c))
@@ -12466,8 +12473,6 @@ c_finish_omp_clauses (tree clauses)
 	case OMP_CLAUSE_COLLAPSE:
 	case OMP_CLAUSE_FINAL:
 	case OMP_CLAUSE_MERGEABLE:
-	case OMP_CLAUSE_SAFELEN:
-	case OMP_CLAUSE_SIMDLEN:
 	case OMP_CLAUSE_DEVICE:
 	case OMP_CLAUSE_DIST_SCHEDULE:
 	case OMP_CLAUSE_PARALLEL:
@@ -12475,6 +12480,12 @@ c_finish_omp_clauses (tree clauses)
 	case OMP_CLAUSE_SECTIONS:
 	case OMP_CLAUSE_TASKGROUP:
 	case OMP_CLAUSE_PROC_BIND:
+	case OMP_CLAUSE_PRIORITY:
+	case OMP_CLAUSE_GRAINSIZE:
+	case OMP_CLAUSE_NUM_TASKS:
+	case OMP_CLAUSE_NOGROUP:
+	case OMP_CLAUSE_THREADS:
+	case OMP_CLAUSE_SIMD:
 	case OMP_CLAUSE__CILK_FOR_COUNT_:
 	case OMP_CLAUSE_NUM_GANGS:
 	case OMP_CLAUSE_NUM_WORKERS:
@@ -12489,6 +12500,15 @@ c_finish_omp_clauses (tree clauses)
 	  pc = &OMP_CLAUSE_CHAIN (c);
 	  continue;
 
+	case OMP_CLAUSE_SAFELEN:
+	  safelen = c;
+	  pc = &OMP_CLAUSE_CHAIN (c);
+	  continue;
+	case OMP_CLAUSE_SIMDLEN:
+	  simdlen = c;
+	  pc = &OMP_CLAUSE_CHAIN (c);
+	  continue;
+
 	case OMP_CLAUSE_INBRANCH:
 	case OMP_CLAUSE_NOTINBRANCH:
 	  if (branch_seen)
@@ -12558,6 +12578,18 @@ c_finish_omp_clauses (tree clauses)
 	pc = &OMP_CLAUSE_CHAIN (c);
     }
 
+  if (simdlen
+      && safelen
+      && tree_int_cst_lt (OMP_CLAUSE_SAFELEN_EXPR (safelen),
+			  OMP_CLAUSE_SIMDLEN_EXPR (simdlen)))
+    {
+      error_at (OMP_CLAUSE_LOCATION (simdlen),
+		"%<simdlen%> clause value is bigger than "
+		"%<safelen%> clause value");
+      OMP_CLAUSE_SIMDLEN_EXPR (simdlen)
+	= OMP_CLAUSE_SAFELEN_EXPR (safelen);
+    }
+
   bitmap_obstack_release (NULL);
   return clauses;
 }
--- gcc/c/c-parser.c.jj	2015-04-29 10:59:20.760504260 +0200
+++ gcc/c/c-parser.c	2015-04-29 11:03:04.641991095 +0200
@@ -1270,6 +1270,7 @@ static bool c_parser_pragma (c_parser *,
 static bool c_parser_omp_target (c_parser *, enum pragma_context);
 static void c_parser_omp_end_declare_target (c_parser *);
 static void c_parser_omp_declare (c_parser *, enum pragma_context);
+static bool c_parser_omp_ordered (c_parser *, enum pragma_context);
 
 /* These Objective-C parser functions are only ever called when
    compiling Objective-C.  */
@@ -9713,6 +9714,11 @@ c_parser_pragma (c_parser *parser, enum
     case PRAGMA_OMP_DECLARE_REDUCTION:
       c_parser_omp_declare (parser, context);
       return false;
+
+    case PRAGMA_OMP_ORDERED:
+      c_parser_omp_ordered (parser, context);
+      return false;
+
     case PRAGMA_IVDEP:
       c_parser_consume_pragma (parser);
       c_parser_skip_to_pragma_eol (parser);
@@ -9897,6 +9903,8 @@ c_parser_omp_clause_name (c_parser *pars
 	case 'g':
 	  if (!strcmp ("gang", p))
 	    result = PRAGMA_OACC_CLAUSE_GANG;
+	  else if (!strcmp ("grainsize", p))
+	    result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
 	  break;
 	case 'h':
 	  if (!strcmp ("host", p))
@@ -9921,12 +9929,16 @@ c_parser_omp_clause_name (c_parser *pars
 	    result = PRAGMA_CILK_CLAUSE_MASK;
 	  break;
 	case 'n':
-	  if (!strcmp ("notinbranch", p))
+	  if (!strcmp ("nogroup", p))
+	    result = PRAGMA_OMP_CLAUSE_NOGROUP;
+	  else if (!strcmp ("notinbranch", p))
 	    result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
 	  else if (!strcmp ("nowait", p))
 	    result = PRAGMA_OMP_CLAUSE_NOWAIT;
 	  else if (!strcmp ("num_gangs", p))
 	    result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
+	  else if (!strcmp ("num_tasks", p))
+	    result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
 	  else if (!strcmp ("num_teams", p))
 	    result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
 	  else if (!strcmp ("num_threads", p))
@@ -9957,6 +9969,8 @@ c_parser_omp_clause_name (c_parser *pars
 	  else if (!strcmp ("present_or_create", p)
 		   || !strcmp ("pcreate", p))
 	    result = PRAGMA_OACC_CLAUSE_PRESENT_OR_CREATE;
+	  else if (!strcmp ("priority", p))
+	    result = PRAGMA_OMP_CLAUSE_PRIORITY;
 	  else if (!strcmp ("private", p))
 	    result = PRAGMA_OMP_CLAUSE_PRIVATE;
 	  else if (!strcmp ("proc_bind", p))
@@ -9977,6 +9991,8 @@ c_parser_omp_clause_name (c_parser *pars
 	    result = PRAGMA_OACC_CLAUSE_SEQ;
 	  else if (!strcmp ("shared", p))
 	    result = PRAGMA_OMP_CLAUSE_SHARED;
+	  else if (!strcmp ("simd", p))
+	    result = PRAGMA_OMP_CLAUSE_SIMD;
 	  else if (!strcmp ("simdlen", p))
 	    result = PRAGMA_OMP_CLAUSE_SIMDLEN;
 	  else if (!strcmp ("self", p))
@@ -9987,6 +10003,8 @@ c_parser_omp_clause_name (c_parser *pars
 	    result = PRAGMA_OMP_CLAUSE_TASKGROUP;
 	  else if (!strcmp ("thread_limit", p))
 	    result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
+	  else if (!strcmp ("threads", p))
+	    result = PRAGMA_OMP_CLAUSE_THREADS;
 	  else if (!strcmp ("to", p))
 	    result = PRAGMA_OMP_CLAUSE_TO;
 	  break;
@@ -10651,6 +10669,139 @@ c_parser_omp_clause_num_threads (c_parse
   return list;
 }
 
+/* OpenMP 4.1:
+   num_tasks ( expression ) */
+
+static tree
+c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
+{
+  location_t num_threads_loc = c_parser_peek_token (parser)->location;
+  if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+    {
+      location_t expr_loc = c_parser_peek_token (parser)->location;
+      tree c, t = c_parser_expression (parser).value;
+      mark_exp_read (t);
+      t = c_fully_fold (t, false, NULL);
+
+      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+
+      if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
+	{
+	  c_parser_error (parser, "expected integer expression");
+	  return list;
+	}
+
+      /* Attempt to statically determine when the number isn't positive.  */
+      c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
+			   build_int_cst (TREE_TYPE (t), 0));
+      if (CAN_HAVE_LOCATION_P (c))
+	SET_EXPR_LOCATION (c, expr_loc);
+      if (c == boolean_true_node)
+	{
+	  warning_at (expr_loc, 0, "%<num_tasks%> value must be positive");
+	  t = integer_one_node;
+	}
+
+      check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
+
+      c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_TASKS);
+      OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
+      OMP_CLAUSE_CHAIN (c) = list;
+      list = c;
+    }
+
+  return list;
+}
+
+/* OpenMP 4.1:
+   grainsize ( expression ) */
+
+static tree
+c_parser_omp_clause_grainsize (c_parser *parser, tree list)
+{
+  location_t num_threads_loc = c_parser_peek_token (parser)->location;
+  if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+    {
+      location_t expr_loc = c_parser_peek_token (parser)->location;
+      tree c, t = c_parser_expression (parser).value;
+      mark_exp_read (t);
+      t = c_fully_fold (t, false, NULL);
+
+      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+
+      if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
+	{
+	  c_parser_error (parser, "expected integer expression");
+	  return list;
+	}
+
+      /* Attempt to statically determine when the number isn't positive.  */
+      c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
+			   build_int_cst (TREE_TYPE (t), 0));
+      if (CAN_HAVE_LOCATION_P (c))
+	SET_EXPR_LOCATION (c, expr_loc);
+      if (c == boolean_true_node)
+	{
+	  warning_at (expr_loc, 0, "%<grainsize%> value must be positive");
+	  t = integer_one_node;
+	}
+
+      check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
+
+      c = build_omp_clause (num_threads_loc, OMP_CLAUSE_GRAINSIZE);
+      OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
+      OMP_CLAUSE_CHAIN (c) = list;
+      list = c;
+    }
+
+  return list;
+}
+
+/* OpenMP 4.1:
+   priority ( expression ) */
+
+static tree
+c_parser_omp_clause_priority (c_parser *parser, tree list)
+{
+  location_t num_threads_loc = c_parser_peek_token (parser)->location;
+  if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+    {
+      location_t expr_loc = c_parser_peek_token (parser)->location;
+      tree c, t = c_parser_expression (parser).value;
+      mark_exp_read (t);
+      t = c_fully_fold (t, false, NULL);
+
+      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+
+      if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
+	{
+	  c_parser_error (parser, "expected integer expression");
+	  return list;
+	}
+
+      /* Attempt to statically determine when the number isn't
+	 non-negative.  */
+      c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
+			   build_int_cst (TREE_TYPE (t), 0));
+      if (CAN_HAVE_LOCATION_P (c))
+	SET_EXPR_LOCATION (c, expr_loc);
+      if (c == boolean_true_node)
+	{
+	  warning_at (expr_loc, 0, "%<priority%> value must be non-negative");
+	  t = integer_one_node;
+	}
+
+      check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
+
+      c = build_omp_clause (num_threads_loc, OMP_CLAUSE_PRIORITY);
+      OMP_CLAUSE_PRIORITY_EXPR (c) = t;
+      OMP_CLAUSE_CHAIN (c) = list;
+      list = c;
+    }
+
+  return list;
+}
+
 /* OpenACC:
    num_workers ( expression ) */
 
@@ -10746,19 +10897,44 @@ c_parser_oacc_clause_wait (c_parser *par
 }
 
 /* OpenMP 2.5:
-   ordered */
+   ordered
+
+   OpenMP 4.1:
+   ordered ( constant-expression ) */
 
 static tree
 c_parser_omp_clause_ordered (c_parser *parser, tree list)
 {
-  tree c;
-
   check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
 
-  c = build_omp_clause (c_parser_peek_token (parser)->location,
-			OMP_CLAUSE_ORDERED);
+  tree c, num = NULL_TREE;
+  HOST_WIDE_INT n;
+  location_t loc = c_parser_peek_token (parser)->location;
+  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
+    {
+      c_parser_consume_token (parser);
+      num = c_parser_expr_no_commas (parser, NULL).value;
+      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+    }
+  if (num == error_mark_node)
+    return list;
+  if (num)
+    {
+      mark_exp_read (num);
+      num = c_fully_fold (num, false, NULL);
+      if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
+	  || !tree_fits_shwi_p (num)
+	  || (n = tree_to_shwi (num)) <= 0
+	  || (int) n != n)
+	{
+	  error_at (loc, "ordered argument needs positive "
+			 "constant integer expression");
+	  return list;
+	}
+    }
+  c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
+  OMP_CLAUSE_ORDERED_EXPR (c) = num;
   OMP_CLAUSE_CHAIN (c) = list;
-
   return c;
 }
 
@@ -11073,6 +11249,33 @@ c_parser_omp_clause_cancelkind (c_parser
   return c;
 }
 
+/* OpenMP 4.1:
+   nogroup */
+
+static tree
+c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
+{
+  check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
+  tree c = build_omp_clause (c_parser_peek_token (parser)->location,
+			     OMP_CLAUSE_NOGROUP);
+  OMP_CLAUSE_CHAIN (c) = list;
+  return c;
+}
+
+/* OpenMP 4.1:
+   simd
+   threads */
+
+static tree
+c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
+				 enum omp_clause_code code, tree list)
+{
+  check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
+  tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
+  OMP_CLAUSE_CHAIN (c) = list;
+  return c;
+}
+
 /* OpenMP 4.0:
    num_teams ( expression ) */
 
@@ -11324,7 +11527,13 @@ c_parser_omp_clause_simdlen (c_parser *p
    depend ( depend-kind: variable-list )
 
    depend-kind:
-     in | out | inout  */
+     in | out | inout
+
+   OpenMP 4.1:
+   depend ( depend-loop-kind [ : vec ] )
+
+   depend-loop-kind:
+     source | sink  */
 
 static tree
 c_parser_omp_clause_depend (c_parser *parser, tree list)
@@ -11345,6 +11554,10 @@ c_parser_omp_clause_depend (c_parser *pa
 	kind = OMP_CLAUSE_DEPEND_INOUT;
       else if (strcmp ("out", p) == 0)
 	kind = OMP_CLAUSE_DEPEND_OUT;
+      else if (strcmp ("source", p) == 0)
+	kind = OMP_CLAUSE_DEPEND_SOURCE;
+      else if (strcmp ("sink", p) == 0)
+	kind = OMP_CLAUSE_DEPEND_SINK;
       else
 	goto invalid_kind;
     }
@@ -11352,6 +11565,19 @@ c_parser_omp_clause_depend (c_parser *pa
     goto invalid_kind;
 
   c_parser_consume_token (parser);
+
+  if (kind == OMP_CLAUSE_DEPEND_SOURCE)
+    {
+      c = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND);
+      OMP_CLAUSE_DEPEND_KIND (c) = kind;
+      OMP_CLAUSE_DECL (c) = NULL_TREE;
+      OMP_CLAUSE_CHAIN (c) = list;
+      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+      return c;
+    }
+
+  /* FIXME: Handle OMP_CLAUSE_DEPEND_SINK.  */
+
   if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
     goto resync_fail;
 
@@ -11376,18 +11602,60 @@ c_parser_omp_clause_depend (c_parser *pa
    map ( variable-list )
 
    map-kind:
-     alloc | to | from | tofrom  */
+     alloc | to | from | tofrom
+
+   OpenMP 4.1:
+   map-kind:
+     alloc | to | from | tofrom | delete
+
+   map ( always [,] map-kind: variable-list ) */
 
 static tree
 c_parser_omp_clause_map (c_parser *parser, tree list)
 {
   location_t clause_loc = c_parser_peek_token (parser)->location;
   enum gomp_map_kind kind = GOMP_MAP_TOFROM;
+  int always = 0;
+  enum c_id_kind always_id_kind = C_ID_NONE;
+  location_t always_loc = UNKNOWN_LOCATION;
+  tree always_id = NULL_TREE;
   tree nl, c;
 
   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
     return list;
 
+  if (c_parser_next_token_is (parser, CPP_NAME))
+    {
+      c_token *tok = c_parser_peek_token (parser);
+      const char *p = IDENTIFIER_POINTER (tok->value);
+      always_id_kind = tok->id_kind;
+      always_loc = tok->location;
+      always_id = tok->value;
+      if (strcmp ("always", p) == 0)
+	{
+	  c_token *sectok = c_parser_peek_2nd_token (parser);
+	  if (sectok->type == CPP_COMMA)
+	    {
+	      c_parser_consume_token (parser);
+	      c_parser_consume_token (parser);
+	      always = 2;
+	    }
+	  else if (sectok->type == CPP_NAME)
+	    {
+	      p = IDENTIFIER_POINTER (sectok->value);
+	      if (strcmp ("alloc", p) == 0
+		  || strcmp ("to", p) == 0
+		  || strcmp ("from", p) == 0
+		  || strcmp ("tofrom", p) == 0
+		  || strcmp ("delete", p) == 0)
+		{
+		  c_parser_consume_token (parser);
+		  always = 1;
+		}
+	    }
+	}
+    }
+
   if (c_parser_next_token_is (parser, CPP_NAME)
       && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
     {
@@ -11400,6 +11668,8 @@ c_parser_omp_clause_map (c_parser *parse
 	kind = GOMP_MAP_FROM;
       else if (strcmp ("tofrom", p) == 0)
 	kind = GOMP_MAP_TOFROM;
+      else if (strcmp ("delete", p) == 0)
+	kind = GOMP_MAP_FORCE_DEALLOC;
       else
 	{
 	  c_parser_error (parser, "invalid map kind");
@@ -11407,9 +11677,40 @@ c_parser_omp_clause_map (c_parser *parse
 				     "expected %<)%>");
 	  return list;
 	}
+      if (always)
+	kind = (enum gomp_map_kind) (kind | GOMP_MAP_FLAG_FORCE);
       c_parser_consume_token (parser);
       c_parser_consume_token (parser);
     }
+  else if (always)
+    {
+      if (always_id_kind != C_ID_ID)
+	{
+	  c_parser_error (parser, "expected identifier");
+	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+	  return list;
+	}
+
+      tree t = lookup_name (always_id);
+      if (t == NULL_TREE)
+	{
+	  undeclared_variable (always_loc, always_id);
+	  t = error_mark_node;
+	}
+      if (t != error_mark_node)
+	{
+	  tree u = build_omp_clause (clause_loc, OMP_CLAUSE_MAP);
+	  OMP_CLAUSE_DECL (u) = t;
+	  OMP_CLAUSE_CHAIN (u) = list;
+	  OMP_CLAUSE_SET_MAP_KIND (u, kind);
+	  list = u;
+	}
+      if (always == 1)
+	{
+	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+	  return list;
+	}
+    }
 
   nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list);
 
@@ -11772,6 +12073,10 @@ c_parser_omp_all_clauses (c_parser *pars
 	  clauses = c_parser_omp_clause_final (parser, clauses);
 	  c_name = "final";
 	  break;
+	case PRAGMA_OMP_CLAUSE_GRAINSIZE:
+	  clauses = c_parser_omp_clause_grainsize (parser, clauses);
+	  c_name = "grainsize";
+	  break;
 	case PRAGMA_OMP_CLAUSE_IF:
 	  clauses = c_parser_omp_clause_if (parser, clauses);
 	  c_name = "if";
@@ -11788,6 +12093,10 @@ c_parser_omp_all_clauses (c_parser *pars
 	  clauses = c_parser_omp_clause_nowait (parser, clauses);
 	  c_name = "nowait";
 	  break;
+	case PRAGMA_OMP_CLAUSE_NUM_TASKS:
+	  clauses = c_parser_omp_clause_num_tasks (parser, clauses);
+	  c_name = "num_tasks";
+	  break;
 	case PRAGMA_OMP_CLAUSE_NUM_THREADS:
 	  clauses = c_parser_omp_clause_num_threads (parser, clauses);
 	  c_name = "num_threads";
@@ -11796,6 +12105,10 @@ c_parser_omp_all_clauses (c_parser *pars
 	  clauses = c_parser_omp_clause_ordered (parser, clauses);
 	  c_name = "ordered";
 	  break;
+	case PRAGMA_OMP_CLAUSE_PRIORITY:
+	  clauses = c_parser_omp_clause_priority (parser, clauses);
+	  c_name = "priority";
+	  break;
 	case PRAGMA_OMP_CLAUSE_PRIVATE:
 	  clauses = c_parser_omp_clause_private (parser, clauses);
 	  c_name = "private";
@@ -11927,6 +12240,22 @@ c_parser_omp_all_clauses (c_parser *pars
 	  clauses = c_parser_omp_clause_simdlen (parser, clauses);
 	  c_name = "simdlen";
 	  break;
+	case PRAGMA_OMP_CLAUSE_NOGROUP:
+	  clauses = c_parser_omp_clause_nogroup (parser, clauses);
+	  c_name = "nogroup";
+	  break;
+	case PRAGMA_OMP_CLAUSE_THREADS:
+	  clauses
+	    = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
+					       clauses);
+	  c_name = "threads";
+	  break;
+	case PRAGMA_OMP_CLAUSE_SIMD:
+	  clauses
+	    = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
+					       clauses);
+	  c_name = "simd";
+	  break;
 	default:
 	  c_parser_error (parser, "expected %<#pragma omp%> clause");
 	  goto saw_error;
@@ -13129,6 +13458,7 @@ omp_split_clauses (location_t loc, enum
 
 #define OMP_SIMD_CLAUSE_MASK					\
 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN)	\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN)	\
 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR)	\
 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED)	\
 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
@@ -13176,6 +13506,7 @@ c_parser_omp_simd (location_t loc, c_par
 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR)	\
 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED)	\
 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)	\
@@ -13259,14 +13590,59 @@ c_parser_omp_master (location_t loc, c_p
    # pragma omp ordered new-line
      structured-block
 
-   LOC is the location of the #pragma itself.
-*/
+   OpenMP 4.1:
+   # pragma omp ordered ordered-clauses new-line
+     structured-block
 
-static tree
-c_parser_omp_ordered (location_t loc, c_parser *parser)
+   # pragma omp ordered depend-clauses new-line  */
+
+#define OMP_ORDERED_CLAUSE_MASK					\
+	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS)	\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
+
+#define OMP_ORDERED_DEPEND_CLAUSE_MASK				\
+	(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)
+
+static bool
+c_parser_omp_ordered (c_parser *parser, enum pragma_context context)
 {
-  c_parser_skip_to_pragma_eol (parser);
-  return c_finish_omp_ordered (loc, c_parser_omp_structured_block (parser));
+  location_t loc = c_parser_peek_token (parser)->location;
+  c_parser_consume_pragma (parser);
+
+  if (context != pragma_stmt && context != pragma_compound)
+    {
+      c_parser_error (parser, "expected declaration specifiers");
+      c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
+      return false;
+    }
+
+  if (c_parser_next_token_is (parser, CPP_NAME))
+    {
+      const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+
+      if (!strcmp ("depend", p))
+	{
+	  if (context == pragma_stmt)
+	    {
+	      error_at (loc,
+			"%<#pragma omp ordered%> with %<depend> clause may "
+			"only be used in compound statements");
+	      c_parser_skip_to_pragma_eol (parser);
+	      return false;
+	    }
+
+	  tree clauses
+	    = c_parser_omp_all_clauses (parser,
+					OMP_ORDERED_DEPEND_CLAUSE_MASK,
+					"#pragma omp ordered");
+	  return c_finish_omp_ordered (loc, clauses, NULL_TREE);
+	}
+    }
+
+  tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
+					   "#pragma omp ordered");
+  return c_finish_omp_ordered (loc, clauses,
+			       c_parser_omp_structured_block (parser));
 }
 
 /* OpenMP 2.5:
@@ -13522,7 +13898,8 @@ c_parser_omp_single (location_t loc, c_p
 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED)	\
 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL)	\
 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE)	\
-	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND))
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY))
 
 static tree
 c_parser_omp_task (location_t loc, c_parser *parser)
@@ -13806,12 +14183,20 @@ c_parser_omp_teams (location_t loc, c_pa
 static tree
 c_parser_omp_target_data (location_t loc, c_parser *parser)
 {
-  tree stmt = make_node (OMP_TARGET_DATA);
-  TREE_TYPE (stmt) = void_type_node;
-
-  OMP_TARGET_DATA_CLAUSES (stmt)
+  tree clauses
     = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
 				"#pragma omp target data");
+  if (find_omp_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
+    {
+      error_at (loc,
+		"%<#pragma omp target data%> must contain at least one "
+		"%<map%> clause");
+      return NULL_TREE;
+    }
+
+  tree stmt = make_node (OMP_TARGET_DATA);
+  TREE_TYPE (stmt) = void_type_node;
+  OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
   keep_next_level ();
   tree block = c_begin_compound_stmt (true);
   add_stmt (c_parser_omp_structured_block (parser));
@@ -13863,6 +14248,169 @@ c_parser_omp_target_update (location_t l
   return false;
 }
 
+/* OpenMP 4.1:
+   # pragma omp target enter data target-data-clause[optseq] new-line  */
+
+#define OMP_TARGET_ENTER_DATA_CLAUSE_MASK			\
+	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)		\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
+
+static tree
+c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
+				enum pragma_context context)
+{
+  bool data_seen = false;
+  if (c_parser_next_token_is (parser, CPP_NAME))
+    {
+      const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+      if (strcmp (p, "data") == 0)
+	{
+	  c_parser_consume_token (parser);
+	  data_seen = true;
+	}
+    }
+  if (!data_seen)
+    {
+      c_parser_error (parser, "expected %<data%>");
+      c_parser_skip_to_pragma_eol (parser);
+      return NULL_TREE;
+    }
+
+  if (context == pragma_stmt)
+    {
+      error_at (loc,
+		"%<#pragma omp target enter data%> may only be "
+		"used in compound statements");
+      c_parser_skip_to_pragma_eol (parser);
+      return NULL_TREE;
+    }
+
+  tree clauses
+    = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
+				"#pragma omp target enter data");
+  int map_seen = 0;
+  for (tree *pc = &clauses; *pc;)
+    {
+      if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
+	switch (OMP_CLAUSE_MAP_KIND (*pc) & ~GOMP_MAP_FLAG_FORCE)
+	  {
+	  case GOMP_MAP_TO:
+	  case GOMP_MAP_ALLOC:
+	    map_seen = 3;
+	    break;
+	  default:
+	    map_seen |= 1;
+	    error_at (OMP_CLAUSE_LOCATION (*pc),
+		      "%<#pragma omp target enter data%> with map-type other "
+		      "than %<to%> or %<alloc%> on %<map%> clause");
+	    *pc = OMP_CLAUSE_CHAIN (*pc);
+	    continue;
+	  }
+      pc = &OMP_CLAUSE_CHAIN (*pc);
+    }
+
+  if (map_seen != 3)
+    {
+      if (map_seen == 0)
+	error_at (loc,
+		  "%<#pragma omp target enter data%> must contain at least "
+		  "one %<map%> clause");
+      return NULL_TREE;
+    }
+
+  tree stmt = make_node (OMP_TARGET_ENTER_DATA);
+  TREE_TYPE (stmt) = void_type_node;
+  OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
+  SET_EXPR_LOCATION (stmt, loc);
+  add_stmt (stmt);
+  return stmt;
+}
+
+/* OpenMP 4.1:
+   # pragma omp target exit data target-data-clause[optseq] new-line  */
+
+#define OMP_TARGET_EXIT_DATA_CLAUSE_MASK			\
+	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)		\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
+
+static tree
+c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
+			       enum pragma_context context)
+{
+  bool data_seen = false;
+  if (c_parser_next_token_is (parser, CPP_NAME))
+    {
+      const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+      if (strcmp (p, "data") == 0)
+	{
+	  c_parser_consume_token (parser);
+	  data_seen = true;
+	}
+    }
+  if (!data_seen)
+    {
+      c_parser_error (parser, "expected %<data%>");
+      c_parser_skip_to_pragma_eol (parser);
+      return NULL_TREE;
+    }
+
+  if (context == pragma_stmt)
+    {
+      error_at (loc,
+		"%<#pragma omp target exit data%> may only be "
+		"used in compound statements");
+      c_parser_skip_to_pragma_eol (parser);
+      return NULL_TREE;
+    }
+
+  tree clauses
+    = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
+				"#pragma omp target exit data");
+
+  int map_seen = 0;
+  for (tree *pc = &clauses; *pc;)
+    {
+      if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
+	switch (OMP_CLAUSE_MAP_KIND (*pc) & ~GOMP_MAP_FLAG_FORCE)
+	  {
+	  case GOMP_MAP_FROM:
+	  case GOMP_MAP_FORCE_DEALLOC & ~GOMP_MAP_FLAG_FORCE:
+	    map_seen = 3;
+	    break;
+	  default:
+	    map_seen |= 1;
+	    error_at (OMP_CLAUSE_LOCATION (*pc),
+		      "%<#pragma omp target exit data%> with map-type other "
+		      "than %<from%> or %<delete%> on %<map%> clause");
+	    *pc = OMP_CLAUSE_CHAIN (*pc);
+	    continue;
+	  }
+      pc = &OMP_CLAUSE_CHAIN (*pc);
+    }
+
+  if (map_seen != 3)
+    {
+      if (map_seen == 0)
+	error_at (loc,
+		  "%<#pragma omp target exit data%> must contain at least one "
+		  "%<map%> clause");
+      return NULL_TREE;
+    }
+
+  tree stmt = make_node (OMP_TARGET_EXIT_DATA);
+  TREE_TYPE (stmt) = void_type_node;
+  OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
+  SET_EXPR_LOCATION (stmt, loc);
+  add_stmt (stmt);
+  return stmt;
+}
+
 /* OpenMP 4.0:
    # pragma omp target target-clause[optseq] new-line
      structured-block  */
@@ -13870,7 +14418,9 @@ c_parser_omp_target_update (location_t l
 #define OMP_TARGET_CLAUSE_MASK					\
 	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
 	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)		\
-	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
 
 static bool
 c_parser_omp_target (c_parser *parser, enum pragma_context context)
@@ -13929,6 +14479,18 @@ c_parser_omp_target (c_parser *parser, e
 	  c_parser_omp_target_data (loc, parser);
 	  return true;
 	}
+      else if (strcmp (p, "enter") == 0)
+	{
+	  c_parser_consume_token (parser);
+	  c_parser_omp_target_enter_data (loc, parser, context);
+	  return true;
+	}
+      else if (strcmp (p, "exit") == 0)
+	{
+	  c_parser_consume_token (parser);
+	  c_parser_omp_target_exit_data (loc, parser, context);
+	  return true;
+	}
       else if (strcmp (p, "update") == 0)
 	{
 	  c_parser_consume_token (parser);
@@ -14619,6 +15181,81 @@ c_parser_omp_declare (c_parser *parser,
   c_parser_skip_to_pragma_eol (parser);
 }
 
+/* OpenMP 4.1:
+   #pragma omp taskloop taskloop-clause[optseq] new-line
+     for-loop  */
+
+#define OMP_TASKLOOP_CLAUSE_MASK				\
+	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED)	\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)	\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE)	\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS)	\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)	\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL)	\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE)	\
+	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
+
+static tree
+c_parser_omp_taskloop (location_t loc, c_parser *parser,
+		       char *p_name, omp_clause_mask mask, tree *cclauses)
+{
+  tree clauses, block, ret;
+
+  strcat (p_name, " taskloop");
+  mask |= OMP_TASKLOOP_CLAUSE_MASK;
+
+  if (c_parser_next_token_is (parser, CPP_NAME))
+    {
+      const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+
+      if (strcmp (p, "simd") == 0)
+	{
+	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
+	  if (cclauses == NULL)
+	    cclauses = cclauses_buf;
+	  mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION);
+	  c_parser_consume_token (parser);
+	  if (!flag_openmp)  /* flag_openmp_simd  */
+	    return c_parser_omp_simd (loc, parser, p_name, mask, cclauses);
+	  block = c_begin_compound_stmt (true);
+	  ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses);
+	  block = c_end_compound_stmt (loc, block, true);
+	  if (ret == NULL)
+	    return ret;
+	  ret = make_node (OMP_TASKLOOP);
+	  TREE_TYPE (ret) = void_type_node;
+	  OMP_FOR_BODY (ret) = block;
+	  OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
+	  SET_EXPR_LOCATION (ret, loc);
+	  add_stmt (ret);
+	  return ret;
+	}
+    }
+  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)
+    {
+      omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
+      clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
+    }
+
+  block = c_begin_compound_stmt (true);
+  ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL);
+  block = c_end_compound_stmt (loc, block, true);
+  add_stmt (block);
+
+  return ret;
+}
+
 /* Main entry point to parsing most OpenMP pragmas.  */
 
 static void
@@ -14676,9 +15313,6 @@ c_parser_omp_construct (c_parser *parser
     case PRAGMA_OMP_MASTER:
       stmt = c_parser_omp_master (loc, parser);
       break;
-    case PRAGMA_OMP_ORDERED:
-      stmt = c_parser_omp_ordered (loc, parser);
-      break;
     case PRAGMA_OMP_PARALLEL:
       strcpy (p_name, "#pragma omp");
       stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL);
@@ -14700,6 +15334,10 @@ c_parser_omp_construct (c_parser *parser
     case PRAGMA_OMP_TASKGROUP:
       stmt = c_parser_omp_taskgroup (parser);
       break;
+    case PRAGMA_OMP_TASKLOOP:
+      strcpy (p_name, "#pragma omp");
+      stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL);
+      break;
     case PRAGMA_OMP_TEAMS:
       strcpy (p_name, "#pragma omp");
       stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL);
--- gcc/c-family/c-omp.c.jj	2015-04-29 10:58:01.644745750 +0200
+++ gcc/c-family/c-omp.c	2015-04-29 11:03:04.641991095 +0200
@@ -122,9 +122,12 @@ c_finish_omp_critical (location_t loc, t
    that follows the pragma.  LOC is the location of the #pragma.  */
 
 tree
-c_finish_omp_ordered (location_t loc, tree stmt)
+c_finish_omp_ordered (location_t loc, tree clauses, tree stmt)
 {
-  tree t = build1 (OMP_ORDERED, void_type_node, stmt);
+  tree t = make_node (OMP_ORDERED);
+  TREE_TYPE (t) = void_type_node;
+  OMP_ORDERED_BODY (t) = stmt;
+  OMP_ORDERED_CLAUSES (t) = clauses;
   SET_EXPR_LOCATION (t, loc);
   return add_stmt (t);
 }
@@ -687,7 +690,7 @@ c_finish_omp_for (location_t locus, enum
     }
 }
 
-/* Right now we have 14 different combined constructs, this
+/* Right now we have 15 different combined constructs, this
    function attempts to split or duplicate clauses for combined
    constructs.  CODE is the innermost construct in the combined construct,
    and MASK allows to determine which constructs are combined together,
@@ -707,7 +710,8 @@ c_finish_omp_for (location_t locus, enum
    #pragma omp target teams
    #pragma omp target teams distribute
    #pragma omp target teams distribute parallel for
-   #pragma omp target teams distribute parallel for simd  */
+   #pragma omp target teams distribute parallel for simd
+   #pragma omp taskloop simd  */
 
 void
 c_omp_split_clauses (location_t loc, enum tree_code code,
@@ -766,11 +770,20 @@ c_omp_split_clauses (location_t loc, enu
 	  s = C_OMP_CLAUSE_SPLIT_FOR;
 	  break;
 	case OMP_CLAUSE_SAFELEN:
+	case OMP_CLAUSE_SIMDLEN:
 	case OMP_CLAUSE_LINEAR:
 	case OMP_CLAUSE_ALIGNED:
 	  s = C_OMP_CLAUSE_SPLIT_SIMD;
 	  break;
-	/* Duplicate this to all of distribute, for and simd.  */
+	case OMP_CLAUSE_GRAINSIZE:
+	case OMP_CLAUSE_NUM_TASKS:
+	case OMP_CLAUSE_FINAL:
+	case OMP_CLAUSE_UNTIED:
+	case OMP_CLAUSE_MERGEABLE:
+	case OMP_CLAUSE_NOGROUP:
+	  s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
+	  break;
+	/* Duplicate this to all of taskloop, distribute, for and simd.  */
 	case OMP_CLAUSE_COLLAPSE:
 	  if (code == OMP_SIMD)
 	    {
@@ -797,6 +810,9 @@ c_omp_split_clauses (location_t loc, enu
 	      else
 		s = C_OMP_CLAUSE_SPLIT_FOR;
 	    }
+	  else if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
+		   != 0)
+	    s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
 	  else
 	    s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
 	  break;
@@ -861,6 +877,13 @@ c_omp_split_clauses (location_t loc, enu
 	      gcc_assert (code == OMP_SIMD);
 	      s = C_OMP_CLAUSE_SPLIT_TEAMS;
 	    }
+	  else if ((mask & (OMP_CLAUSE_MASK_1
+			    << PRAGMA_OMP_CLAUSE_NOGROUP)) != 0)
+	    {
+	      /* This must be #pragma omp taskloop simd.  */
+	      gcc_assert (code == OMP_SIMD);
+	      s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
+	    }
 	  else
 	    {
 	      /* This must be #pragma omp for simd.  */
@@ -905,6 +928,12 @@ c_omp_split_clauses (location_t loc, enu
 	      s = C_OMP_CLAUSE_SPLIT_TEAMS;
 	      break;
 	    }
+	  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
+	      != 0)
+	    {
+	      s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
+	      break;
+	    }
 	  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS))
 	      != 0)
 	    {
@@ -965,9 +994,12 @@ c_omp_split_clauses (location_t loc, enu
 	    s = C_OMP_CLAUSE_SPLIT_TEAMS;
 	  break;
 	case OMP_CLAUSE_IF:
-	  /* FIXME: This is currently being discussed.  */
-	  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS))
+	  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
 	      != 0)
+	    s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
+	  /* FIXME: This is currently being discussed.  */
+	  else if ((mask & (OMP_CLAUSE_MASK_1
+			    << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
 	    s = C_OMP_CLAUSE_SPLIT_PARALLEL;
 	  else
 	    s = C_OMP_CLAUSE_SPLIT_TARGET;
--- gcc/c-family/c-pragma.h.jj	2015-04-29 10:58:01.645745734 +0200
+++ gcc/c-family/c-pragma.h	2015-04-29 11:03:04.642991080 +0200
@@ -36,6 +36,7 @@ typedef enum pragma_kind {
   PRAGMA_OACC_PARALLEL,
   PRAGMA_OACC_UPDATE,
   PRAGMA_OACC_WAIT,
+
   PRAGMA_OMP_ATOMIC,
   PRAGMA_OMP_BARRIER,
   PRAGMA_OMP_CANCEL,
@@ -56,6 +57,7 @@ typedef enum pragma_kind {
   PRAGMA_OMP_TARGET,
   PRAGMA_OMP_TASK,
   PRAGMA_OMP_TASKGROUP,
+  PRAGMA_OMP_TASKLOOP,
   PRAGMA_OMP_TASKWAIT,
   PRAGMA_OMP_TASKYIELD,
   PRAGMA_OMP_THREADPRIVATE,
@@ -74,7 +76,7 @@ typedef enum pragma_kind {
 } pragma_kind;
 
 
-/* All clauses defined by OpenACC 2.0, and OpenMP 2.5, 3.0, 3.1, and 4.0.
+/* All clauses defined by OpenACC 2.0, and OpenMP 2.5, 3.0, 3.1, 4.0 and 4.1.
    Used internally by both C and C++ parsers.  */
 typedef enum pragma_omp_clause {
   PRAGMA_OMP_CLAUSE_NONE = 0,
@@ -91,18 +93,22 @@ typedef enum pragma_omp_clause {
   PRAGMA_OMP_CLAUSE_FIRSTPRIVATE,
   PRAGMA_OMP_CLAUSE_FOR,
   PRAGMA_OMP_CLAUSE_FROM,
+  PRAGMA_OMP_CLAUSE_GRAINSIZE,
   PRAGMA_OMP_CLAUSE_IF,
   PRAGMA_OMP_CLAUSE_INBRANCH,
   PRAGMA_OMP_CLAUSE_LASTPRIVATE,
   PRAGMA_OMP_CLAUSE_LINEAR,
   PRAGMA_OMP_CLAUSE_MAP,
   PRAGMA_OMP_CLAUSE_MERGEABLE,
+  PRAGMA_OMP_CLAUSE_NOGROUP,
   PRAGMA_OMP_CLAUSE_NOTINBRANCH,
   PRAGMA_OMP_CLAUSE_NOWAIT,
+  PRAGMA_OMP_CLAUSE_NUM_TASKS,
   PRAGMA_OMP_CLAUSE_NUM_TEAMS,
   PRAGMA_OMP_CLAUSE_NUM_THREADS,
   PRAGMA_OMP_CLAUSE_ORDERED,
   PRAGMA_OMP_CLAUSE_PARALLEL,
+  PRAGMA_OMP_CLAUSE_PRIORITY,
   PRAGMA_OMP_CLAUSE_PRIVATE,
   PRAGMA_OMP_CLAUSE_PROC_BIND,
   PRAGMA_OMP_CLAUSE_REDUCTION,
@@ -110,13 +116,15 @@ typedef enum pragma_omp_clause {
   PRAGMA_OMP_CLAUSE_SCHEDULE,
   PRAGMA_OMP_CLAUSE_SECTIONS,
   PRAGMA_OMP_CLAUSE_SHARED,
+  PRAGMA_OMP_CLAUSE_SIMD,
   PRAGMA_OMP_CLAUSE_SIMDLEN,
   PRAGMA_OMP_CLAUSE_TASKGROUP,
   PRAGMA_OMP_CLAUSE_THREAD_LIMIT,
+  PRAGMA_OMP_CLAUSE_THREADS,
   PRAGMA_OMP_CLAUSE_TO,
   PRAGMA_OMP_CLAUSE_UNIFORM,
   PRAGMA_OMP_CLAUSE_UNTIED,
-  
+
   /* Clauses for Cilk Plus SIMD-enabled function.  */
   PRAGMA_CILK_CLAUSE_NOMASK,
   PRAGMA_CILK_CLAUSE_MASK,
--- gcc/c-family/c-common.h.jj	2015-04-29 10:59:19.553523200 +0200
+++ gcc/c-family/c-common.h	2015-04-29 11:03:04.642991080 +0200
@@ -1228,13 +1228,14 @@ enum c_omp_clause_split
   C_OMP_CLAUSE_SPLIT_FOR,
   C_OMP_CLAUSE_SPLIT_SIMD,
   C_OMP_CLAUSE_SPLIT_COUNT,
-  C_OMP_CLAUSE_SPLIT_SECTIONS = C_OMP_CLAUSE_SPLIT_FOR
+  C_OMP_CLAUSE_SPLIT_SECTIONS = C_OMP_CLAUSE_SPLIT_FOR,
+  C_OMP_CLAUSE_SPLIT_TASKLOOP = C_OMP_CLAUSE_SPLIT_FOR
 };
 
 extern tree c_finish_omp_master (location_t, tree);
 extern tree c_finish_omp_taskgroup (location_t, tree);
 extern tree c_finish_omp_critical (location_t, tree, tree);
-extern tree c_finish_omp_ordered (location_t, tree);
+extern tree c_finish_omp_ordered (location_t, tree, tree);
 extern void c_finish_omp_barrier (location_t);
 extern tree c_finish_omp_atomic (location_t, enum tree_code, enum tree_code,
 				 tree, tree, tree, tree, tree, bool, bool);
--- gcc/tree-core.h.jj	2015-04-29 10:58:01.646745719 +0200
+++ gcc/tree-core.h	2015-04-29 11:03:04.643991064 +0200
@@ -310,7 +310,7 @@ enum omp_clause_code {
   /* OpenMP clause: nowait.  */
   OMP_CLAUSE_NOWAIT,
 
-  /* OpenMP clause: ordered.  */
+  /* OpenMP clause: ordered [(constant-integer-expression)].  */
   OMP_CLAUSE_ORDERED,
 
   /* OpenMP clause: default.  */
@@ -367,6 +367,24 @@ enum omp_clause_code {
   /* OpenMP clause: taskgroup.  */
   OMP_CLAUSE_TASKGROUP,
 
+  /* OpenMP clause: priority (integer-expression).  */
+  OMP_CLAUSE_PRIORITY,
+
+  /* OpenMP clause: grainsize (integer-expression).  */
+  OMP_CLAUSE_GRAINSIZE,
+
+  /* OpenMP clause: num_tasks (integer-expression).  */
+  OMP_CLAUSE_NUM_TASKS,
+
+  /* OpenMP clause: nogroup.  */
+  OMP_CLAUSE_NOGROUP,
+
+  /* OpenMP clause: threads.  */
+  OMP_CLAUSE_THREADS,
+
+  /* OpenMP clause: simd.  */
+  OMP_CLAUSE_SIMD,
+
   /* Internally used only clause, holding SIMD uid.  */
   OMP_CLAUSE__SIMDUID_,
 
@@ -1227,6 +1245,8 @@ enum omp_clause_depend_kind
   OMP_CLAUSE_DEPEND_IN,
   OMP_CLAUSE_DEPEND_OUT,
   OMP_CLAUSE_DEPEND_INOUT,
+  OMP_CLAUSE_DEPEND_SOURCE,
+  OMP_CLAUSE_DEPEND_SINK,
   OMP_CLAUSE_DEPEND_LAST
 };
 
--- gcc/omp-low.c.jj	2015-04-29 10:58:01.489748182 +0200
+++ gcc/omp-low.c	2015-04-29 11:03:04.646991017 +0200
@@ -1809,6 +1809,9 @@ scan_sharing_clauses (tree clauses, omp_
 	case OMP_CLAUSE_SCHEDULE:
 	case OMP_CLAUSE_DIST_SCHEDULE:
 	case OMP_CLAUSE_DEPEND:
+	case OMP_CLAUSE_PRIORITY:
+	case OMP_CLAUSE_GRAINSIZE:
+	case OMP_CLAUSE_NUM_TASKS:
 	case OMP_CLAUSE__CILK_FOR_COUNT_:
 	case OMP_CLAUSE_NUM_GANGS:
 	case OMP_CLAUSE_NUM_WORKERS:
@@ -1908,6 +1911,10 @@ scan_sharing_clauses (tree clauses, omp_
 	case OMP_CLAUSE_MERGEABLE:
 	case OMP_CLAUSE_PROC_BIND:
 	case OMP_CLAUSE_SAFELEN:
+	case OMP_CLAUSE_SIMDLEN:
+	case OMP_CLAUSE_THREADS:
+	case OMP_CLAUSE_SIMD:
+	case OMP_CLAUSE_NOGROUP:
 	case OMP_CLAUSE_ASYNC:
 	case OMP_CLAUSE_WAIT:
 	case OMP_CLAUSE_GANG:
@@ -2033,11 +2040,18 @@ scan_sharing_clauses (tree clauses, omp_
 	case OMP_CLAUSE_MERGEABLE:
 	case OMP_CLAUSE_PROC_BIND:
 	case OMP_CLAUSE_SAFELEN:
+	case OMP_CLAUSE_SIMDLEN:
 	case OMP_CLAUSE_ALIGNED:
 	case OMP_CLAUSE_DEPEND:
 	case OMP_CLAUSE__LOOPTEMP_:
 	case OMP_CLAUSE_TO:
 	case OMP_CLAUSE_FROM:
+	case OMP_CLAUSE_PRIORITY:
+	case OMP_CLAUSE_GRAINSIZE:
+	case OMP_CLAUSE_NUM_TASKS:
+	case OMP_CLAUSE_THREADS:
+	case OMP_CLAUSE_SIMD:
+	case OMP_CLAUSE_NOGROUP:
 	case OMP_CLAUSE__CILK_FOR_COUNT_:
 	case OMP_CLAUSE_ASYNC:
 	case OMP_CLAUSE_WAIT:
@@ -3030,19 +3044,26 @@ check_omp_nesting_restrictions (gimple s
 	    case GF_OMP_TARGET_KIND_REGION: stmt_name = "target"; break;
 	    case GF_OMP_TARGET_KIND_DATA: stmt_name = "target data"; break;
 	    case GF_OMP_TARGET_KIND_UPDATE: stmt_name = "target update"; break;
+	    case GF_OMP_TARGET_KIND_ENTER_DATA:
+	      stmt_name = "target enter data"; break;
+	    case GF_OMP_TARGET_KIND_EXIT_DATA:
+	      stmt_name = "target exit data"; break;
 	    case GF_OMP_TARGET_KIND_OACC_PARALLEL: stmt_name = "parallel"; break;
 	    case GF_OMP_TARGET_KIND_OACC_KERNELS: stmt_name = "kernels"; break;
 	    case GF_OMP_TARGET_KIND_OACC_DATA: stmt_name = "data"; break;
 	    case GF_OMP_TARGET_KIND_OACC_UPDATE: stmt_name = "update"; break;
-	    case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA: stmt_name = "enter/exit data"; break;
+	    case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
+	      stmt_name = "enter/exit data"; break;
 	    default: gcc_unreachable ();
 	    }
 	  switch (gimple_omp_target_kind (ctx->stmt))
 	    {
 	    case GF_OMP_TARGET_KIND_REGION: ctx_stmt_name = "target"; break;
 	    case GF_OMP_TARGET_KIND_DATA: ctx_stmt_name = "target data"; break;
-	    case GF_OMP_TARGET_KIND_OACC_PARALLEL: ctx_stmt_name = "parallel"; break;
-	    case GF_OMP_TARGET_KIND_OACC_KERNELS: ctx_stmt_name = "kernels"; break;
+	    case GF_OMP_TARGET_KIND_OACC_PARALLEL:
+	      ctx_stmt_name = "parallel"; break;
+	    case GF_OMP_TARGET_KIND_OACC_KERNELS:
+	      ctx_stmt_name = "kernels"; break;
 	    case GF_OMP_TARGET_KIND_OACC_DATA: ctx_stmt_name = "data"; break;
 	    default: gcc_unreachable ();
 	    }
@@ -8785,6 +8806,8 @@ expand_omp_target (struct omp_region *re
     {
     case GF_OMP_TARGET_KIND_REGION:
     case GF_OMP_TARGET_KIND_UPDATE:
+    case GF_OMP_TARGET_KIND_ENTER_DATA:
+    case GF_OMP_TARGET_KIND_EXIT_DATA:
     case GF_OMP_TARGET_KIND_OACC_PARALLEL:
     case GF_OMP_TARGET_KIND_OACC_KERNELS:
     case GF_OMP_TARGET_KIND_OACC_UPDATE:
@@ -8994,6 +9017,11 @@ expand_omp_target (struct omp_region *re
     case GF_OMP_TARGET_KIND_UPDATE:
       start_ix = BUILT_IN_GOMP_TARGET_UPDATE;
       break;
+    case GF_OMP_TARGET_KIND_ENTER_DATA:
+    case GF_OMP_TARGET_KIND_EXIT_DATA:
+      /* FIXME */
+      start_ix = BUILT_IN_GOMP_TARGET_UPDATE;
+      break;
     case GF_OMP_TARGET_KIND_OACC_PARALLEL:
     case GF_OMP_TARGET_KIND_OACC_KERNELS:
       start_ix = BUILT_IN_GOACC_PARALLEL;
@@ -9396,6 +9424,8 @@ build_omp_regions_1 (basic_block bb, str
 		case GF_OMP_TARGET_KIND_OACC_DATA:
 		  break;
 		case GF_OMP_TARGET_KIND_UPDATE:
+		case GF_OMP_TARGET_KIND_ENTER_DATA:
+		case GF_OMP_TARGET_KIND_EXIT_DATA:
 		case GF_OMP_TARGET_KIND_OACC_UPDATE:
 		case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
 		  /* ..., other than for those stand-alone directives...  */
@@ -11198,6 +11228,8 @@ lower_omp_target (gimple_stmt_iterator *
     {
     case GF_OMP_TARGET_KIND_REGION:
     case GF_OMP_TARGET_KIND_UPDATE:
+    case GF_OMP_TARGET_KIND_ENTER_DATA:
+    case GF_OMP_TARGET_KIND_EXIT_DATA:
     case GF_OMP_TARGET_KIND_OACC_PARALLEL:
     case GF_OMP_TARGET_KIND_OACC_KERNELS:
     case GF_OMP_TARGET_KIND_OACC_UPDATE:
@@ -11251,13 +11283,13 @@ lower_omp_target (gimple_stmt_iterator *
 	  case GOMP_MAP_TOFROM:
 	  case GOMP_MAP_POINTER:
 	  case GOMP_MAP_TO_PSET:
-	    break;
 	  case GOMP_MAP_FORCE_ALLOC:
 	  case GOMP_MAP_FORCE_TO:
 	  case GOMP_MAP_FORCE_FROM:
 	  case GOMP_MAP_FORCE_TOFROM:
 	  case GOMP_MAP_FORCE_PRESENT:
 	  case GOMP_MAP_FORCE_DEALLOC:
+	    break;
 	  case GOMP_MAP_FORCE_DEVICEPTR:
 	    gcc_assert (is_gimple_omp_oacc (stmt));
 	    break;
@@ -11488,6 +11520,9 @@ lower_omp_target (gimple_stmt_iterator *
 	      default:
 		gcc_unreachable ();
 	      }
+	    /* FIXME: Temporary hack.  */
+	    if (talign_shift == 3)
+	      tkind &= ~GOMP_MAP_FLAG_FORCE;
 	    gcc_checking_assert (tkind
 				 < (HOST_WIDE_INT_C (1U) << talign_shift));
 	    talign = ceil_log2 (talign);
@@ -12244,6 +12279,8 @@ make_gimple_omp_edges (basic_block bb, s
 	case GF_OMP_TARGET_KIND_OACC_DATA:
 	  break;
 	case GF_OMP_TARGET_KIND_UPDATE:
+	case GF_OMP_TARGET_KIND_ENTER_DATA:
+	case GF_OMP_TARGET_KIND_EXIT_DATA:
 	case GF_OMP_TARGET_KIND_OACC_UPDATE:
 	case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA:
 	  cur_region = cur_region->outer;
--- gcc/fortran/trans-openmp.c.jj	2015-04-29 10:59:40.236198646 +0200
+++ gcc/fortran/trans-openmp.c	2015-04-29 11:15:45.535945145 +0200
@@ -2356,6 +2356,7 @@ gfc_trans_omp_clauses (stmtblock_t *bloc
   if (clauses->ordered)
     {
       c = build_omp_clause (where.lb->location, OMP_CLAUSE_ORDERED);
+      OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
       omp_clauses = gfc_trans_add_clause (c, omp_clauses);
     }
 
@@ -2531,6 +2532,7 @@ gfc_trans_omp_clauses (stmtblock_t *bloc
   if (clauses->seq)
     {
       c = build_omp_clause (where.lb->location, OMP_CLAUSE_ORDERED);
+      OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
       omp_clauses = gfc_trans_add_clause (c, omp_clauses);
     }
   if (clauses->independent)
@@ -3494,7 +3496,8 @@ gfc_trans_omp_master (gfc_code *code)
 static tree
 gfc_trans_omp_ordered (gfc_code *code)
 {
-  return build1_v (OMP_ORDERED, gfc_trans_code (code->block->next));
+  return build2_loc (input_location, OMP_ORDERED, void_type_node,
+		     gfc_trans_code (code->block->next), NULL_TREE);
 }
 
 static tree
--- gcc/tree-pretty-print.c.jj	2015-04-29 10:58:01.663745452 +0200
+++ gcc/tree-pretty-print.c	2015-04-29 11:03:04.648990986 +0200
@@ -404,6 +404,13 @@ dump_omp_clause (pretty_printer *pp, tre
       break;
     case OMP_CLAUSE_ORDERED:
       pp_string (pp, "ordered");
+      if (OMP_CLAUSE_ORDERED_EXPR (clause))
+	{
+	  pp_left_paren (pp);
+	  dump_generic_node (pp, OMP_CLAUSE_ORDERED_EXPR (clause),
+			     spc, flags, false);
+	  pp_right_paren (pp);
+	}
       break;
 
     case OMP_CLAUSE_DEFAULT:
@@ -522,6 +529,9 @@ dump_omp_clause (pretty_printer *pp, tre
 	case OMP_CLAUSE_DEPEND_INOUT:
 	  pp_string (pp, "inout");
 	  break;
+	case OMP_CLAUSE_DEPEND_SOURCE:
+	  pp_string (pp, "source)");
+	  return;
 	default:
 	  gcc_unreachable ();
 	}
@@ -550,22 +560,22 @@ dump_omp_clause (pretty_printer *pp, tre
 	  pp_string (pp, "tofrom");
 	  break;
 	case GOMP_MAP_FORCE_ALLOC:
-	  pp_string (pp, "force_alloc");
+	  pp_string (pp, "always,alloc");
 	  break;
 	case GOMP_MAP_FORCE_TO:
-	  pp_string (pp, "force_to");
+	  pp_string (pp, "always,to");
 	  break;
 	case GOMP_MAP_FORCE_FROM:
-	  pp_string (pp, "force_from");
+	  pp_string (pp, "always,from");
 	  break;
 	case GOMP_MAP_FORCE_TOFROM:
-	  pp_string (pp, "force_tofrom");
+	  pp_string (pp, "always,tofrom");
 	  break;
 	case GOMP_MAP_FORCE_PRESENT:
 	  pp_string (pp, "force_present");
 	  break;
 	case GOMP_MAP_FORCE_DEALLOC:
-	  pp_string (pp, "force_dealloc");
+	  pp_string (pp, "always,delete");
 	  break;
 	case GOMP_MAP_FORCE_DEVICEPTR:
 	  pp_string (pp, "force_deviceptr");
@@ -678,6 +688,27 @@ dump_omp_clause (pretty_printer *pp, tre
       pp_right_paren (pp);
       break;
 
+    case OMP_CLAUSE_PRIORITY:
+      pp_string (pp, "priority(");
+      dump_generic_node (pp, OMP_CLAUSE_PRIORITY_EXPR (clause),
+			 spc, flags, false);
+      pp_right_paren (pp);
+      break;
+
+    case OMP_CLAUSE_GRAINSIZE:
+      pp_string (pp, "grainsize(");
+      dump_generic_node (pp, OMP_CLAUSE_GRAINSIZE_EXPR (clause),
+			 spc, flags, false);
+      pp_right_paren (pp);
+      break;
+
+    case OMP_CLAUSE_NUM_TASKS:
+      pp_string (pp, "num_tasks(");
+      dump_generic_node (pp, OMP_CLAUSE_NUM_TASKS_EXPR (clause),
+			 spc, flags, false);
+      pp_right_paren (pp);
+      break;
+
     case OMP_CLAUSE__SIMDUID_:
       pp_string (pp, "_simduid_(");
       dump_generic_node (pp, OMP_CLAUSE__SIMDUID__DECL (clause),
@@ -796,6 +827,15 @@ dump_omp_clause (pretty_printer *pp, tre
     case OMP_CLAUSE_TASKGROUP:
       pp_string (pp, "taskgroup");
       break;
+    case OMP_CLAUSE_NOGROUP:
+      pp_string (pp, "nogroup");
+      break;
+    case OMP_CLAUSE_THREADS:
+      pp_string (pp, "threads");
+      break;
+    case OMP_CLAUSE_SIMD:
+      pp_string (pp, "simd");
+      break;
     case OMP_CLAUSE_INDEPENDENT:
       pp_string (pp, "independent");
       break;
@@ -2652,6 +2692,10 @@ dump_generic_node (pretty_printer *pp, t
       pp_string (pp, "#pragma omp distribute");
       goto dump_omp_loop;
 
+    case OMP_TASKLOOP:
+      pp_string (pp, "#pragma omp taskloop");
+      goto dump_omp_loop;
+
     case OACC_LOOP:
       pp_string (pp, "#pragma acc loop");
       goto dump_omp_loop;
@@ -2666,6 +2710,18 @@ dump_generic_node (pretty_printer *pp, t
       dump_omp_clauses (pp, OMP_TARGET_DATA_CLAUSES (node), spc, flags);
       goto dump_omp_body;
 
+    case OMP_TARGET_ENTER_DATA:
+      pp_string (pp, "#pragma omp target enter data");
+      dump_omp_clauses (pp, OMP_TARGET_ENTER_DATA_CLAUSES (node), spc, flags);
+      is_expr = false;
+      break;
+
+    case OMP_TARGET_EXIT_DATA:
+      pp_string (pp, "#pragma omp target exit data");
+      dump_omp_clauses (pp, OMP_TARGET_EXIT_DATA_CLAUSES (node), spc, flags);
+      is_expr = false;
+      break;
+
     case OMP_TARGET:
       pp_string (pp, "#pragma omp target");
       dump_omp_clauses (pp, OMP_TARGET_CLAUSES (node), spc, flags);
@@ -2766,6 +2822,7 @@ dump_generic_node (pretty_printer *pp, t
 
     case OMP_ORDERED:
       pp_string (pp, "#pragma omp ordered");
+      dump_omp_clauses (pp, OMP_ORDERED_CLAUSES (node), spc, flags);
       goto dump_omp_body;
 
     case OMP_CRITICAL:

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]