diff mbox

[gomp4.5] Further progress on OpenMP 4.5 parsing

Message ID 20160513110825.GM28550@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek May 13, 2016, 11:08 a.m. UTC
Hi!

This patch adds parsing of new OpenMP 4.5 constructs (though, collapse(n)
is still not handled), but we don't do anything about those during resolve
and later.

Committed to gomp-4_5-branch.

2016-05-13  Jakub Jelinek  <jakub@redhat.com>

	* parse.c (decode_omp_directive): Use gfc_match_omp_end_critical
	instead of gfc_match_omp_critical for !$omp end critical.
	Handle new OpenMP 4.5 constructs.
	(case_executable): Add ST_OMP_TARGET_ENTER_DATA and
	ST_OMP_TARGET_EXIT_DATA cases.
	(case_exec_markers): Add ST_OMP_TARGET_PARALLEL,
	ST_OMP_TARGET_PARALLEL_DO, ST_OMP_TARGET_PARALLEL_DO_SIMD,
	ST_OMP_TARGET_SIMD, ST_OMP_TASKLOOP and ST_OMP_TASKLOOP_SIMD cases.
	(gfc_ascii_statement): Handle new OpenMP 4.5 constructs.
	(parse_omp_do): Handle ST_OMP_TARGET_PARALLEL_DO,
	ST_OMP_TARGET_PARALLEL_DO_SIMD, ST_OMP_TASKLOOP and
	ST_OMP_TASKLOOP_SIMD.
	(parse_omp_structured_block): Handle EXEC_OMP_END_CRITICAL instead
	of EXEC_OMP_CRITICAL, adjust for EXEC_OMP_CRITICAL having omp clauses
	now.
	(parse_executable): Handle ST_OMP_TARGET_PARALLEL,
	ST_OMP_TARGET_PARALLEL_DO, ST_OMP_TARGET_PARALLEL_DO_SIMD,
	ST_OMP_TASKLOOP and ST_OMP_TASKLOOP_SIMD.
	* st.c (gfc_free_statement): Handle EXEC_OMP_END_CRITICAL like
	EXEC_OMP_CRITICAL before, free clauses for EXEC_OMP_CRITICAL
	and new OpenMP 4.5 constructs.
	* dump-parse-tree.c (show_omp_node): Formatting fixes.  Adjust
	handling of EXEC_OMP_CRITICAL, handle new OpenMP 4.5 constructs
	and some forgotten OpenMP 4.0 constructs.
	(show_code_node): Handle new OpenMP 4.5 constructs and some forgotten
	OpenMP 4.0 constructs.
	* trans-openmp.c (gfc_trans_omp_critical): Adjust EXEC_OMP_CRITICAL
	handling.
	* gfortran.h (enum gfc_statement): Add ST_OMP_TARGET_PARALLEL,
	ST_OMP_END_TARGET_PARALLEL, ST_OMP_TARGET_PARALLEL_DO,
	ST_OMP_END_TARGET_PARALLEL_DO, ST_OMP_TARGET_PARALLEL_DO_SIMD,
	ST_OMP_END_TARGET_PARALLEL_DO_SIMD, ST_OMP_TARGET_ENTER_DATA,
	ST_OMP_TARGET_EXIT_DATA, ST_OMP_TARGET_SIMD, ST_OMP_END_TARGET_SIMD,
	ST_OMP_TASKLOOP, ST_OMP_END_TASKLOOP, ST_OMP_TASKLOOP_SIMD and
	ST_OMP_END_TASKLOOP_SIMD.
	(struct gfc_omp_clauses): Add critical_name field.
	(enum gfc_exec_op): Add EXEC_OMP_END_CRITICAL,
	EXEC_OMP_TARGET_ENTER_DATA, EXEC_OMP_TARGET_EXIT_DATA,
	EXEC_OMP_TARGET_PARALLEL, EXEC_OMP_TARGET_PARALLEL_DO,
	EXEC_OMP_TARGET_PARALLEL_DO_SIMD, EXEC_OMP_TARGET_SIMD,
	EXEC_OMP_TASKLOOP, EXEC_OMP_TASKLOOP_SIMD.
	* frontend-passes.c (gfc_code_walker): Handle EXEC_OMP_CRITICAL,
	EXEC_OMP_TASKLOOP, EXEC_OMP_TASKLOOP_SIMD, EXEC_OMP_TARGET_ENTER_DATA,
	EXEC_OMP_TARGET_EXIT_DATA, EXEC_OMP_TARGET_PARALLEL,
	EXEC_OMP_TARGET_PARALLEL_DO, EXEC_OMP_TARGET_PARALLEL_DO_SIMD and
	EXEC_OMP_TARGET_SIMD.
	* openmp.c (gfc_free_omp_clauses): Free critical_name field.
	(OMP_DO_CLAUSES): Add OMP_CLAUSE_LINEAR.
	(OMP_SIMD_CLAUSES): Add OMP_CLAUSE_SIMDLEN.
	(OMP_TASKLOOP_CLAUSES, OMP_TARGET_ENTER_DATA_CLAUSES,
	OMP_TARGET_EXIT_DATA_CLAUSES): Define.
	(gfc_match_omp_critical): Parse optional clauses and use omp_clauses
	union member instead of omp_name.
	(gfc_match_omp_end_critical): New function.
	(gfc_match_omp_distribute_parallel_do): Remove ordered and linear
	clauses from the mask.
	(gfc_match_omp_do_simd): Don't remove ordered clause from the mask.
	(gfc_match_omp_parallel_do_simd): Likewise.
	(gfc_match_omp_task, gfc_match_omp_taskwait, gfc_match_omp_taskyield):
	Move around to where they belong alphabetically.
	(gfc_match_omp_target_enter_data, gfc_match_omp_target_exit_data,
	gfc_match_omp_target_parallel, gfc_match_omp_target_parallel_do,
	gfc_match_omp_target_parallel_do_simd, gfc_match_omp_target_simd): New
	functions.
	(gfc_match_omp_target_teams_distribute_parallel_do): Remove ordered
	and linear clauses from the mask.
	(gfc_match_omp_taskloop, gfc_match_omp_taskloop_simd): New functions.
	(gfc_match_omp_teams_distribute_parallel_do): Remove ordered and
	linear clauses from the mask.
	* match.h (gfc_match_omp_target_enter_data,
	gfc_match_omp_target_exit_data, gfc_match_omp_target_parallel,
	gfc_match_omp_target_parallel_do,
	gfc_match_omp_target_parallel_do_simd, gfc_match_omp_target_simd,
	gfc_match_omp_taskloop, gfc_match_omp_taskloop_simd,
	gfc_match_omp_end_critical): New prototypes.

	* gfortran.dg/gomp/target1.f90: Remove ordered clause where it is
	no longer allowed and corresponding ordered construct.


	Jakub
diff mbox

Patch

--- gcc/fortran/parse.c.jj	2016-05-04 18:37:35.000000000 +0200
+++ gcc/fortran/parse.c	2016-05-13 11:49:47.887238121 +0200
@@ -765,7 +765,7 @@  decode_omp_directive (void)
       break;
     case 'e':
       matcho ("end atomic", gfc_match_omp_eos, ST_OMP_END_ATOMIC);
-      matcho ("end critical", gfc_match_omp_critical, ST_OMP_END_CRITICAL);
+      matcho ("end critical", gfc_match_omp_end_critical, ST_OMP_END_CRITICAL);
       matchs ("end distribute parallel do simd", gfc_match_omp_eos,
 	      ST_OMP_END_DISTRIBUTE_PARALLEL_DO_SIMD);
       matcho ("end distribute parallel do", gfc_match_omp_eos,
@@ -789,6 +789,13 @@  decode_omp_directive (void)
       matcho ("end sections", gfc_match_omp_end_nowait, ST_OMP_END_SECTIONS);
       matcho ("end single", gfc_match_omp_end_single, ST_OMP_END_SINGLE);
       matcho ("end target data", gfc_match_omp_eos, ST_OMP_END_TARGET_DATA);
+      matchs ("end target parallel do simd", gfc_match_omp_eos,
+	      ST_OMP_END_TARGET_PARALLEL_DO_SIMD);
+      matcho ("end target parallel do", gfc_match_omp_eos,
+	      ST_OMP_END_TARGET_PARALLEL_DO);
+      matcho ("end target parallel", gfc_match_omp_eos,
+	      ST_OMP_END_TARGET_PARALLEL);
+      matchs ("end target simd", gfc_match_omp_eos, ST_OMP_END_TARGET_SIMD);
       matchs ("end target teams distribute parallel do simd",
 	      gfc_match_omp_eos,
 	      ST_OMP_END_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD);
@@ -801,6 +808,9 @@  decode_omp_directive (void)
       matcho ("end target teams", gfc_match_omp_eos, ST_OMP_END_TARGET_TEAMS);
       matcho ("end target", gfc_match_omp_eos, ST_OMP_END_TARGET);
       matcho ("end taskgroup", gfc_match_omp_eos, ST_OMP_END_TASKGROUP);
+      matchs ("end taskloop simd", gfc_match_omp_eos,
+	      ST_OMP_END_TASKLOOP_SIMD);
+      matcho ("end taskloop", gfc_match_omp_eos, ST_OMP_END_TASKLOOP);
       matcho ("end task", gfc_match_omp_eos, ST_OMP_END_TASK);
       matchs ("end teams distribute parallel do simd", gfc_match_omp_eos,
 	      ST_OMP_END_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD);
@@ -841,6 +851,17 @@  decode_omp_directive (void)
       break;
     case 't':
       matcho ("target data", gfc_match_omp_target_data, ST_OMP_TARGET_DATA);
+      matcho ("target enter data", gfc_match_omp_target_enter_data,
+	      ST_OMP_TARGET_ENTER_DATA);
+      matcho ("target exit data", gfc_match_omp_target_exit_data,
+	      ST_OMP_TARGET_EXIT_DATA);
+      matchs ("target parallel do simd", gfc_match_omp_target_parallel_do_simd,
+	      ST_OMP_TARGET_PARALLEL_DO_SIMD);
+      matcho ("target parallel do", gfc_match_omp_target_parallel_do,
+	      ST_OMP_TARGET_PARALLEL_DO);
+      matcho ("target parallel", gfc_match_omp_target_parallel,
+	      ST_OMP_TARGET_PARALLEL);
+      matchs ("target simd", gfc_match_omp_target_simd, ST_OMP_TARGET_SIMD);
       matchs ("target teams distribute parallel do simd",
 	      gfc_match_omp_target_teams_distribute_parallel_do_simd,
 	      ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD);
@@ -857,6 +878,9 @@  decode_omp_directive (void)
 	      ST_OMP_TARGET_UPDATE);
       matcho ("target", gfc_match_omp_target, ST_OMP_TARGET);
       matcho ("taskgroup", gfc_match_omp_taskgroup, ST_OMP_TASKGROUP);
+      matchs ("taskloop simd", gfc_match_omp_taskloop_simd,
+	      ST_OMP_TASKLOOP_SIMD);
+      matcho ("taskloop", gfc_match_omp_taskloop, ST_OMP_TASKLOOP);
       matcho ("taskwait", gfc_match_omp_taskwait, ST_OMP_TASKWAIT);
       matcho ("taskyield", gfc_match_omp_taskyield, ST_OMP_TASKYIELD);
       matcho ("task", gfc_match_omp_task, ST_OMP_TASK);
@@ -1348,7 +1372,8 @@  next_statement (void)
   case ST_LABEL_ASSIGNMENT: case ST_FLUSH: case ST_OMP_FLUSH: \
   case ST_OMP_BARRIER: case ST_OMP_TASKWAIT: case ST_OMP_TASKYIELD: \
   case ST_OMP_CANCEL: case ST_OMP_CANCELLATION_POINT: \
-  case ST_OMP_TARGET_UPDATE: case ST_ERROR_STOP: case ST_SYNC_ALL: \
+  case ST_OMP_TARGET_UPDATE: case ST_OMP_TARGET_ENTER_DATA: \
+  case ST_OMP_TARGET_EXIT_DATA: case ST_ERROR_STOP: case ST_SYNC_ALL: \
   case ST_SYNC_IMAGES: case ST_SYNC_MEMORY: case ST_LOCK: case ST_UNLOCK: \
   case ST_EVENT_POST: case ST_EVENT_WAIT: \
   case ST_OACC_UPDATE: case ST_OACC_WAIT: case ST_OACC_CACHE: \
@@ -1376,7 +1401,9 @@  next_statement (void)
   case ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO: \
   case ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD: case ST_OMP_DISTRIBUTE: \
   case ST_OMP_DISTRIBUTE_SIMD: case ST_OMP_DISTRIBUTE_PARALLEL_DO: \
-  case ST_OMP_DISTRIBUTE_PARALLEL_DO_SIMD: \
+  case ST_OMP_DISTRIBUTE_PARALLEL_DO_SIMD: case ST_OMP_TARGET_PARALLEL: \
+  case ST_OMP_TARGET_PARALLEL_DO: case ST_OMP_TARGET_PARALLEL_DO_SIMD: \
+  case ST_OMP_TARGET_SIMD: case ST_OMP_TASKLOOP: case ST_OMP_TASKLOOP_SIMD: \
   case ST_CRITICAL: \
   case ST_OACC_PARALLEL_LOOP: case ST_OACC_PARALLEL: case ST_OACC_KERNELS: \
   case ST_OACC_DATA: case ST_OACC_HOST_DATA: case ST_OACC_LOOP: \
@@ -2061,6 +2088,18 @@  gfc_ascii_statement (gfc_statement st)
     case ST_OMP_END_TARGET_DATA:
       p = "!$OMP END TARGET DATA";
       break;
+    case ST_OMP_END_TARGET_PARALLEL:
+      p = "!$OMP END TARGET PARALLEL";
+      break;
+    case ST_OMP_END_TARGET_PARALLEL_DO:
+      p = "!$OMP END TARGET PARALLEL DO";
+      break;
+    case ST_OMP_END_TARGET_PARALLEL_DO_SIMD:
+      p = "!$OMP END TARGET PARALLEL DO SIMD";
+      break;
+    case ST_OMP_END_TARGET_SIMD:
+      p = "!$OMP END TARGET SIMD";
+      break;
     case ST_OMP_END_TARGET_TEAMS:
       p = "!$OMP END TARGET TEAMS";
       break;
@@ -2079,6 +2118,12 @@  gfc_ascii_statement (gfc_statement st)
     case ST_OMP_END_TASKGROUP:
       p = "!$OMP END TASKGROUP";
       break;
+    case ST_OMP_END_TASKLOOP:
+      p = "!$OMP END TASKLOOP";
+      break;
+    case ST_OMP_END_TASKLOOP_SIMD:
+      p = "!$OMP END TASKLOOP SIMD";
+      break;
     case ST_OMP_END_TEAMS:
       p = "!$OMP END TEAMS";
       break;
@@ -2139,6 +2184,24 @@  gfc_ascii_statement (gfc_statement st)
     case ST_OMP_TARGET_DATA:
       p = "!$OMP TARGET DATA";
       break;
+    case ST_OMP_TARGET_ENTER_DATA:
+      p = "!$OMP TARGET ENTER DATA";
+      break;
+    case ST_OMP_TARGET_EXIT_DATA:
+      p = "!$OMP TARGET EXIT DATA";
+      break;
+    case ST_OMP_TARGET_PARALLEL:
+      p = "!$OMP TARGET PARALLEL";
+      break;
+    case ST_OMP_TARGET_PARALLEL_DO:
+      p = "!$OMP TARGET PARALLEL DO";
+      break;
+    case ST_OMP_TARGET_PARALLEL_DO_SIMD:
+      p = "!$OMP TARGET PARALLEL DO SIMD";
+      break;
+    case ST_OMP_TARGET_SIMD:
+      p = "!$OMP TARGET SIMD";
+      break;
     case ST_OMP_TARGET_TEAMS:
       p = "!$OMP TARGET TEAMS";
       break;
@@ -2163,6 +2226,12 @@  gfc_ascii_statement (gfc_statement st)
     case ST_OMP_TASKGROUP:
       p = "!$OMP TASKGROUP";
       break;
+    case ST_OMP_TASKLOOP:
+      p = "!$OMP TASKLOOP";
+      break;
+    case ST_OMP_TASKLOOP_SIMD:
+      p = "!$OMP TASKLOOP SIMD";
+      break;
     case ST_OMP_TASKWAIT:
       p = "!$OMP TASKWAIT";
       break;
@@ -4332,6 +4401,13 @@  parse_omp_do (gfc_statement omp_st)
       omp_end_st = ST_OMP_END_PARALLEL_DO_SIMD;
       break;
     case ST_OMP_SIMD: omp_end_st = ST_OMP_END_SIMD; break;
+    case ST_OMP_TARGET_PARALLEL_DO:
+      omp_end_st = ST_OMP_END_TARGET_PARALLEL_DO;
+      break;
+    case ST_OMP_TARGET_PARALLEL_DO_SIMD:
+      omp_end_st = ST_OMP_END_TARGET_PARALLEL_DO_SIMD;
+      break;
+    case ST_OMP_TARGET_SIMD: omp_end_st = ST_OMP_END_TARGET_SIMD; break;
     case ST_OMP_TARGET_TEAMS_DISTRIBUTE:
       omp_end_st = ST_OMP_END_TARGET_TEAMS_DISTRIBUTE;
       break;
@@ -4344,6 +4420,8 @@  parse_omp_do (gfc_statement omp_st)
     case ST_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
       omp_end_st = ST_OMP_END_TARGET_TEAMS_DISTRIBUTE_SIMD;
       break;
+    case ST_OMP_TASKLOOP: omp_end_st = ST_OMP_END_TASKLOOP; break;
+    case ST_OMP_TASKLOOP_SIMD: omp_end_st = ST_OMP_END_TASKLOOP_SIMD; break;
     case ST_OMP_TEAMS_DISTRIBUTE:
       omp_end_st = ST_OMP_END_TEAMS_DISTRIBUTE;
       break;
@@ -4752,13 +4830,15 @@  parse_omp_structured_block (gfc_statemen
     case EXEC_OMP_END_NOWAIT:
       cp->ext.omp_clauses->nowait |= new_st.ext.omp_bool;
       break;
-    case EXEC_OMP_CRITICAL:
-      if (((cp->ext.omp_name == NULL) ^ (new_st.ext.omp_name == NULL))
+    case EXEC_OMP_END_CRITICAL:
+      if (((cp->ext.omp_clauses == NULL) ^ (new_st.ext.omp_name == NULL))
 	  || (new_st.ext.omp_name != NULL
-	      && strcmp (cp->ext.omp_name, new_st.ext.omp_name) != 0))
+	      && strcmp (cp->ext.omp_clauses->critical_name,
+			 new_st.ext.omp_name) != 0))
 	gfc_error ("Name after !$omp critical and !$omp end critical does "
 		   "not match at %C");
       free (CONST_CAST (char *, new_st.ext.omp_name));
+      new_st.ext.omp_name = NULL;
       break;
     case EXEC_OMP_END_SINGLE:
       cp->ext.omp_clauses->lists[OMP_LIST_COPYPRIVATE]
@@ -4901,6 +4981,7 @@  parse_executable (gfc_statement st)
 	case ST_OMP_SINGLE:
 	case ST_OMP_TARGET:
 	case ST_OMP_TARGET_DATA:
+	case ST_OMP_TARGET_PARALLEL:
 	case ST_OMP_TARGET_TEAMS:
 	case ST_OMP_TEAMS:
 	case ST_OMP_TASK:
@@ -4922,10 +5003,14 @@  parse_executable (gfc_statement st)
 	case ST_OMP_PARALLEL_DO:
 	case ST_OMP_PARALLEL_DO_SIMD:
 	case ST_OMP_SIMD:
+	case ST_OMP_TARGET_PARALLEL_DO:
+	case ST_OMP_TARGET_PARALLEL_DO_SIMD:
 	case ST_OMP_TARGET_TEAMS_DISTRIBUTE:
 	case ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
 	case ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
 	case ST_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
+	case ST_OMP_TASKLOOP:
+	case ST_OMP_TASKLOOP_SIMD:
 	case ST_OMP_TEAMS_DISTRIBUTE:
 	case ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
 	case ST_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
--- gcc/fortran/st.c.jj	2016-05-04 18:37:33.000000000 +0200
+++ gcc/fortran/st.c	2016-05-13 11:58:31.235358748 +0200
@@ -207,6 +207,7 @@  gfc_free_statement (gfc_code *p)
     case EXEC_OACC_ROUTINE:
     case EXEC_OMP_CANCEL:
     case EXEC_OMP_CANCELLATION_POINT:
+    case EXEC_OMP_CRITICAL:
     case EXEC_OMP_DISTRIBUTE:
     case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
     case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
@@ -218,11 +219,18 @@  gfc_free_statement (gfc_code *p)
     case EXEC_OMP_PARALLEL_DO:
     case EXEC_OMP_PARALLEL_DO_SIMD:
     case EXEC_OMP_PARALLEL_SECTIONS:
+    case EXEC_OMP_PARALLEL_WORKSHARE:
     case EXEC_OMP_SECTIONS:
     case EXEC_OMP_SIMD:
     case EXEC_OMP_SINGLE:
     case EXEC_OMP_TARGET:
     case EXEC_OMP_TARGET_DATA:
+    case EXEC_OMP_TARGET_ENTER_DATA:
+    case EXEC_OMP_TARGET_EXIT_DATA:
+    case EXEC_OMP_TARGET_PARALLEL:
+    case EXEC_OMP_TARGET_PARALLEL_DO:
+    case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
+    case EXEC_OMP_TARGET_SIMD:
     case EXEC_OMP_TARGET_TEAMS:
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
@@ -230,17 +238,18 @@  gfc_free_statement (gfc_code *p)
     case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
     case EXEC_OMP_TARGET_UPDATE:
     case EXEC_OMP_TASK:
+    case EXEC_OMP_TASKLOOP:
+    case EXEC_OMP_TASKLOOP_SIMD:
     case EXEC_OMP_TEAMS:
     case EXEC_OMP_TEAMS_DISTRIBUTE:
     case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
     case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
     case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
     case EXEC_OMP_WORKSHARE:
-    case EXEC_OMP_PARALLEL_WORKSHARE:
       gfc_free_omp_clauses (p->ext.omp_clauses);
       break;
 
-    case EXEC_OMP_CRITICAL:
+    case EXEC_OMP_END_CRITICAL:
       free (CONST_CAST (char *, p->ext.omp_name));
       break;
 
--- gcc/fortran/dump-parse-tree.c.jj	2016-05-06 19:15:24.000000000 +0200
+++ gcc/fortran/dump-parse-tree.c	2016-05-13 12:07:43.927081146 +0200
@@ -1427,7 +1427,8 @@  show_omp_node (int level, gfc_code *c)
 
   switch (c->op)
     {
-    case EXEC_OACC_PARALLEL_LOOP: name = "PARALLEL LOOP"; is_oacc = true; break;
+    case EXEC_OACC_PARALLEL_LOOP:
+      name = "PARALLEL LOOP"; is_oacc = true; break;
     case EXEC_OACC_PARALLEL: name = "PARALLEL"; is_oacc = true; break;
     case EXEC_OACC_KERNELS_LOOP: name = "KERNELS LOOP"; is_oacc = true; break;
     case EXEC_OACC_KERNELS: name = "KERNELS"; is_oacc = true; break;
@@ -1444,9 +1445,15 @@  show_omp_node (int level, gfc_code *c)
     case EXEC_OMP_CANCEL: name = "CANCEL"; break;
     case EXEC_OMP_CANCELLATION_POINT: name = "CANCELLATION POINT"; break;
     case EXEC_OMP_CRITICAL: name = "CRITICAL"; break;
-    case EXEC_OMP_FLUSH: name = "FLUSH"; break;
+    case EXEC_OMP_DISTRIBUTE: name = "DISTRIBUTE"; break;
+    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
+      name = "DISTRIBUTE PARALLEL DO"; break;
+    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
+      name = "DISTRIBUTE PARALLEL DO SIMD"; break;
+    case EXEC_OMP_DISTRIBUTE_SIMD: name = "DISTRIBUTE SIMD"; break;
     case EXEC_OMP_DO: name = "DO"; break;
     case EXEC_OMP_DO_SIMD: name = "DO SIMD"; break;
+    case EXEC_OMP_FLUSH: name = "FLUSH"; break;
     case EXEC_OMP_MASTER: name = "MASTER"; break;
     case EXEC_OMP_ORDERED: name = "ORDERED"; break;
     case EXEC_OMP_PARALLEL: name = "PARALLEL"; break;
@@ -1457,10 +1464,38 @@  show_omp_node (int level, gfc_code *c)
     case EXEC_OMP_SECTIONS: name = "SECTIONS"; break;
     case EXEC_OMP_SIMD: name = "SIMD"; break;
     case EXEC_OMP_SINGLE: name = "SINGLE"; break;
+    case EXEC_OMP_TARGET: name = "TARGET"; break;
+    case EXEC_OMP_TARGET_DATA: name = "TARGET DATA"; break;
+    case EXEC_OMP_TARGET_ENTER_DATA: name = "TARGET ENTER DATA"; break;
+    case EXEC_OMP_TARGET_EXIT_DATA: name = "TARGET EXIT DATA"; break;
+    case EXEC_OMP_TARGET_PARALLEL: name = "TARGET PARALLEL"; break;
+    case EXEC_OMP_TARGET_PARALLEL_DO: name = "TARGET PARALLEL DO"; break;
+    case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
+      name = "TARGET_PARALLEL_DO_SIMD"; break;
+    case EXEC_OMP_TARGET_SIMD: name = "TARGET SIMD"; break;
+    case EXEC_OMP_TARGET_TEAMS: name = "TARGET TEAMS"; break;
+    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
+      name = "TARGET TEAMS DISTRIBUTE"; break;
+    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
+      name = "TARGET TEAMS DISTRIBUTE PARALLEL DO"; break;
+    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
+      name = "TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD"; break;
+    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
+      name = "TARGET TEAMS DISTRIBUTE SIMD"; break;
+    case EXEC_OMP_TARGET_UPDATE: name = "TARGET UPDATE"; break;
     case EXEC_OMP_TASK: name = "TASK"; break;
     case EXEC_OMP_TASKGROUP: name = "TASKGROUP"; break;
+    case EXEC_OMP_TASKLOOP: name = "TASKLOOP"; break;
+    case EXEC_OMP_TASKLOOP_SIMD: name = "TASKLOOP SIMD"; break;
     case EXEC_OMP_TASKWAIT: name = "TASKWAIT"; break;
     case EXEC_OMP_TASKYIELD: name = "TASKYIELD"; break;
+    case EXEC_OMP_TEAMS: name = "TEAMS"; break;
+    case EXEC_OMP_TEAMS_DISTRIBUTE: name = "TEAMS DISTRIBUTE"; break;
+    case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
+      name = "TEAMS DISTRIBUTE PARALLEL DO"; break;
+    case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
+      name = "TEAMS DISTRIBUTE PARALLEL DO SIMD"; break;
+    case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD: name = "TEAMS DISTRIBUTE SIMD"; break;
     case EXEC_OMP_WORKSHARE: name = "WORKSHARE"; break;
     default:
       gcc_unreachable ();
@@ -1482,23 +1517,49 @@  show_omp_node (int level, gfc_code *c)
     case EXEC_OACC_EXIT_DATA:
     case EXEC_OMP_CANCEL:
     case EXEC_OMP_CANCELLATION_POINT:
+    case EXEC_OMP_DISTRIBUTE:
+    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
+    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
+    case EXEC_OMP_DISTRIBUTE_SIMD:
     case EXEC_OMP_DO:
     case EXEC_OMP_DO_SIMD:
     case EXEC_OMP_PARALLEL:
     case EXEC_OMP_PARALLEL_DO:
     case EXEC_OMP_PARALLEL_DO_SIMD:
     case EXEC_OMP_PARALLEL_SECTIONS:
+    case EXEC_OMP_PARALLEL_WORKSHARE:
     case EXEC_OMP_SECTIONS:
     case EXEC_OMP_SIMD:
     case EXEC_OMP_SINGLE:
-    case EXEC_OMP_WORKSHARE:
-    case EXEC_OMP_PARALLEL_WORKSHARE:
+    case EXEC_OMP_TARGET:
+    case EXEC_OMP_TARGET_DATA:
+    case EXEC_OMP_TARGET_ENTER_DATA:
+    case EXEC_OMP_TARGET_EXIT_DATA:
+    case EXEC_OMP_TARGET_PARALLEL:
+    case EXEC_OMP_TARGET_PARALLEL_DO:
+    case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
+    case EXEC_OMP_TARGET_SIMD:
+    case EXEC_OMP_TARGET_TEAMS:
+    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
+    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
+    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
+    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
+    case EXEC_OMP_TARGET_UPDATE:
     case EXEC_OMP_TASK:
+    case EXEC_OMP_TASKLOOP:
+    case EXEC_OMP_TASKLOOP_SIMD:
+    case EXEC_OMP_TEAMS:
+    case EXEC_OMP_TEAMS_DISTRIBUTE:
+    case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
+    case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
+    case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
+    case EXEC_OMP_WORKSHARE:
       omp_clauses = c->ext.omp_clauses;
       break;
     case EXEC_OMP_CRITICAL:
-      if (c->ext.omp_name)
-	fprintf (dumpfile, " (%s)", c->ext.omp_name);
+      omp_clauses = c->ext.omp_clauses;
+      if (omp_clauses)
+	fprintf (dumpfile, " (%s)", c->ext.omp_clauses->critical_name);
       break;
     case EXEC_OMP_FLUSH:
       if (c->ext.omp_namelist)
@@ -1519,9 +1580,11 @@  show_omp_node (int level, gfc_code *c)
     show_omp_clauses (omp_clauses);
   fputc ('\n', dumpfile);
 
-  /* OpenACC executable directives don't have associated blocks.  */
+  /* OpenMP and OpenACC executable directives don't have associated blocks.  */
   if (c->op == EXEC_OACC_CACHE || c->op == EXEC_OACC_UPDATE
-      || c->op == EXEC_OACC_ENTER_DATA || c->op == EXEC_OACC_EXIT_DATA)
+      || c->op == EXEC_OACC_ENTER_DATA || c->op == EXEC_OACC_EXIT_DATA
+      || c->op == EXEC_OMP_TARGET_UPDATE || c->op == EXEC_OMP_TARGET_ENTER_DATA
+      || c->op == EXEC_OMP_TARGET_EXIT_DATA)
     return;
   if (c->op == EXEC_OMP_SECTIONS || c->op == EXEC_OMP_PARALLEL_SECTIONS)
     {
@@ -1555,8 +1618,8 @@  show_omp_node (int level, gfc_code *c)
       else if (omp_clauses->nowait)
 	fputs (" NOWAIT", dumpfile);
     }
-  else if (c->op == EXEC_OMP_CRITICAL && c->ext.omp_name)
-    fprintf (dumpfile, " (%s)", c->ext.omp_name);
+  else if (c->op == EXEC_OMP_CRITICAL && c->ext.omp_clauses)
+    fprintf (dumpfile, " (%s)", c->ext.omp_clauses->critical_name);
 }
 
 
@@ -2578,9 +2641,13 @@  show_code_node (int level, gfc_code *c)
     case EXEC_OMP_CANCELLATION_POINT:
     case EXEC_OMP_BARRIER:
     case EXEC_OMP_CRITICAL:
-    case EXEC_OMP_FLUSH:
+    case EXEC_OMP_DISTRIBUTE:
+    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
+    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
+    case EXEC_OMP_DISTRIBUTE_SIMD:
     case EXEC_OMP_DO:
     case EXEC_OMP_DO_SIMD:
+    case EXEC_OMP_FLUSH:
     case EXEC_OMP_MASTER:
     case EXEC_OMP_ORDERED:
     case EXEC_OMP_PARALLEL:
@@ -2591,10 +2658,31 @@  show_code_node (int level, gfc_code *c)
     case EXEC_OMP_SECTIONS:
     case EXEC_OMP_SIMD:
     case EXEC_OMP_SINGLE:
+    case EXEC_OMP_TARGET:
+    case EXEC_OMP_TARGET_DATA:
+    case EXEC_OMP_TARGET_ENTER_DATA:
+    case EXEC_OMP_TARGET_EXIT_DATA:
+    case EXEC_OMP_TARGET_PARALLEL:
+    case EXEC_OMP_TARGET_PARALLEL_DO:
+    case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
+    case EXEC_OMP_TARGET_SIMD:
+    case EXEC_OMP_TARGET_TEAMS:
+    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
+    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
+    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
+    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
+    case EXEC_OMP_TARGET_UPDATE:
     case EXEC_OMP_TASK:
     case EXEC_OMP_TASKGROUP:
+    case EXEC_OMP_TASKLOOP:
+    case EXEC_OMP_TASKLOOP_SIMD:
     case EXEC_OMP_TASKWAIT:
     case EXEC_OMP_TASKYIELD:
+    case EXEC_OMP_TEAMS:
+    case EXEC_OMP_TEAMS_DISTRIBUTE:
+    case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
+    case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
+    case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
     case EXEC_OMP_WORKSHARE:
       show_omp_node (level, c);
       break;
--- gcc/fortran/trans-openmp.c.jj	2016-05-04 18:37:26.000000000 +0200
+++ gcc/fortran/trans-openmp.c	2016-05-13 11:49:47.887238121 +0200
@@ -3124,8 +3124,8 @@  static tree
 gfc_trans_omp_critical (gfc_code *code)
 {
   tree name = NULL_TREE, stmt;
-  if (code->ext.omp_name != NULL)
-    name = get_identifier (code->ext.omp_name);
+  if (code->ext.omp_clauses != NULL)
+    name = get_identifier (code->ext.omp_clauses->critical_name);
   stmt = gfc_trans_code (code->block->next);
   return build3_loc (input_location, OMP_CRITICAL, void_type_node, stmt,
 		     NULL_TREE, name);
--- gcc/fortran/gfortran.h.jj	2016-05-06 19:01:13.000000000 +0200
+++ gcc/fortran/gfortran.h	2016-05-09 18:33:32.934529112 +0200
@@ -240,6 +240,13 @@  enum gfc_statement
   ST_OMP_END_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD,
   ST_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD,
   ST_OMP_END_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD,
+  ST_OMP_TARGET_PARALLEL, ST_OMP_END_TARGET_PARALLEL,
+  ST_OMP_TARGET_PARALLEL_DO, ST_OMP_END_TARGET_PARALLEL_DO,
+  ST_OMP_TARGET_PARALLEL_DO_SIMD, ST_OMP_END_TARGET_PARALLEL_DO_SIMD,
+  ST_OMP_TARGET_ENTER_DATA, ST_OMP_TARGET_EXIT_DATA,
+  ST_OMP_TARGET_SIMD, ST_OMP_END_TARGET_SIMD,
+  ST_OMP_TASKLOOP, ST_OMP_END_TASKLOOP,
+  ST_OMP_TASKLOOP_SIMD, ST_OMP_END_TASKLOOP_SIMD,
   ST_PROCEDURE, ST_GENERIC, ST_CRITICAL, ST_END_CRITICAL,
   ST_GET_FCN_CHARACTERISTICS, ST_LOCK, ST_UNLOCK, ST_EVENT_POST,
   ST_EVENT_WAIT,ST_NONE
@@ -1254,6 +1261,7 @@  typedef struct gfc_omp_clauses
   struct gfc_expr *if_exprs[OMP_IF_LAST];
   enum gfc_omp_sched_kind dist_sched_kind;
   struct gfc_expr *dist_chunk_size;
+  const char *critical_name;
 
   /* OpenACC. */
   struct gfc_expr *async_expr;
@@ -2421,7 +2429,11 @@  enum gfc_exec_op
   EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO,
   EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD,
   EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD,
-  EXEC_OMP_TARGET_UPDATE
+  EXEC_OMP_TARGET_UPDATE, EXEC_OMP_END_CRITICAL,
+  EXEC_OMP_TARGET_ENTER_DATA, EXEC_OMP_TARGET_EXIT_DATA,
+  EXEC_OMP_TARGET_PARALLEL, EXEC_OMP_TARGET_PARALLEL_DO,
+  EXEC_OMP_TARGET_PARALLEL_DO_SIMD, EXEC_OMP_TARGET_SIMD,
+  EXEC_OMP_TASKLOOP, EXEC_OMP_TASKLOOP_SIMD
 };
 
 enum gfc_omp_atomic_op
--- gcc/fortran/frontend-passes.c.jj	2016-05-06 18:57:25.000000000 +0200
+++ gcc/fortran/frontend-passes.c	2016-05-13 11:51:54.401575256 +0200
@@ -3586,6 +3586,7 @@  gfc_code_walker (gfc_code **c, walk_code
 
 	      /* Fall through  */
 
+	    case EXEC_OMP_CRITICAL:
 	    case EXEC_OMP_DISTRIBUTE:
 	    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
 	    case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
@@ -3596,8 +3597,16 @@  gfc_code_walker (gfc_code **c, walk_code
 	    case EXEC_OMP_SINGLE:
 	    case EXEC_OMP_END_SINGLE:
 	    case EXEC_OMP_SIMD:
+	    case EXEC_OMP_TASKLOOP:
+	    case EXEC_OMP_TASKLOOP_SIMD:
 	    case EXEC_OMP_TARGET:
 	    case EXEC_OMP_TARGET_DATA:
+	    case EXEC_OMP_TARGET_ENTER_DATA:
+	    case EXEC_OMP_TARGET_EXIT_DATA:
+	    case EXEC_OMP_TARGET_PARALLEL:
+	    case EXEC_OMP_TARGET_PARALLEL_DO:
+	    case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
+	    case EXEC_OMP_TARGET_SIMD:
 	    case EXEC_OMP_TARGET_TEAMS:
 	    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
 	    case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
--- gcc/fortran/openmp.c.jj	2016-05-06 19:00:17.000000000 +0200
+++ gcc/fortran/openmp.c	2016-05-13 11:49:47.887238121 +0200
@@ -94,6 +94,7 @@  gfc_free_omp_clauses (gfc_omp_clauses *c
     gfc_free_omp_namelist (c->lists[i]);
   gfc_free_expr_list (c->wait_list);
   gfc_free_expr_list (c->tile_list);
+  free (CONST_CAST (char *, c->critical_name));
   free (c);
 }
 
@@ -2148,19 +2149,26 @@  cleanup:
 #define OMP_DO_CLAUSES \
   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE		\
    | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION			\
-   | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED | OMP_CLAUSE_COLLAPSE)
+   | OMP_CLAUSE_SCHEDULE | OMP_CLAUSE_ORDERED | OMP_CLAUSE_COLLAPSE	\
+   | OMP_CLAUSE_LINEAR)
 #define OMP_SECTIONS_CLAUSES \
   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE		\
    | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_REDUCTION)
 #define OMP_SIMD_CLAUSES \
   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_LASTPRIVATE		\
    | OMP_CLAUSE_REDUCTION | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_SAFELEN	\
-   | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ALIGNED)
+   | OMP_CLAUSE_LINEAR | OMP_CLAUSE_ALIGNED | OMP_CLAUSE_SIMDLEN)
 #define OMP_TASK_CLAUSES \
   (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE		\
    | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF | OMP_CLAUSE_DEFAULT		\
    | OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL | OMP_CLAUSE_MERGEABLE	\
    | OMP_CLAUSE_DEPEND | OMP_CLAUSE_PRIORITY)
+#define OMP_TASKLOOP_CLAUSES \
+  (omp_mask (OMP_CLAUSE_PRIVATE) | OMP_CLAUSE_FIRSTPRIVATE		\
+   | OMP_CLAUSE_LASTPRIVATE | OMP_CLAUSE_SHARED | OMP_CLAUSE_IF		\
+   | OMP_CLAUSE_DEFAULT	| OMP_CLAUSE_UNTIED | OMP_CLAUSE_FINAL		\
+   | OMP_CLAUSE_MERGEABLE | OMP_CLAUSE_PRIORITY | OMP_CLAUSE_GRAINSIZE	\
+   | OMP_CLAUSE_NUM_TASKS | OMP_CLAUSE_COLLAPSE | OMP_CLAUSE_NOGROUP)
 #define OMP_TARGET_CLAUSES \
   (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF	\
    | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT | OMP_CLAUSE_PRIVATE		\
@@ -2169,6 +2177,12 @@  cleanup:
 #define OMP_TARGET_DATA_CLAUSES \
   (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF	\
    | OMP_CLAUSE_USE_DEVICE_PTR)
+#define OMP_TARGET_ENTER_DATA_CLAUSES \
+  (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF	\
+   | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
+#define OMP_TARGET_EXIT_DATA_CLAUSES \
+  (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_MAP | OMP_CLAUSE_IF	\
+   | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
 #define OMP_TARGET_UPDATE_CLAUSES \
   (omp_mask (OMP_CLAUSE_DEVICE) | OMP_CLAUSE_IF | OMP_CLAUSE_TO		\
    | OMP_CLAUSE_FROM | OMP_CLAUSE_DEPEND | OMP_CLAUSE_NOWAIT)
@@ -2199,6 +2213,32 @@  match
 gfc_match_omp_critical (void)
 {
   char n[GFC_MAX_SYMBOL_LEN+1];
+  gfc_omp_clauses *c = NULL;
+
+  if (gfc_match (" ( %n )", n) != MATCH_YES)
+    {
+      n[0] = '\0';
+      if (gfc_match_omp_eos () != MATCH_YES)
+	{
+	  gfc_error ("Unexpected junk after $OMP CRITICAL statement at %C");
+	  return MATCH_ERROR;
+	}
+    }
+  else if (gfc_match_omp_clauses (&c, omp_mask (OMP_CLAUSE_HINT)) != MATCH_YES)
+    return MATCH_ERROR;
+
+  new_st.op = EXEC_OMP_CRITICAL;
+  new_st.ext.omp_clauses = c;
+  if (n[0])
+    c->critical_name = xstrdup (n);
+  return MATCH_YES;
+}
+
+
+match
+gfc_match_omp_end_critical (void)
+{
+  char n[GFC_MAX_SYMBOL_LEN+1];
 
   if (gfc_match (" ( %n )", n) != MATCH_YES)
     n[0] = '\0';
@@ -2207,7 +2247,8 @@  gfc_match_omp_critical (void)
       gfc_error ("Unexpected junk after $OMP CRITICAL statement at %C");
       return MATCH_ERROR;
     }
-  new_st.op = EXEC_OMP_CRITICAL;
+
+  new_st.op = EXEC_OMP_END_CRITICAL;
   new_st.ext.omp_name = n[0] ? xstrdup (n) : NULL;
   return MATCH_YES;
 }
@@ -2224,8 +2265,10 @@  match
 gfc_match_omp_distribute_parallel_do (void)
 {
   return match_omp (EXEC_OMP_DISTRIBUTE_PARALLEL_DO,
-		    OMP_DISTRIBUTE_CLAUSES | OMP_PARALLEL_CLAUSES
-		    | OMP_DO_CLAUSES);
+		    (OMP_DISTRIBUTE_CLAUSES | OMP_PARALLEL_CLAUSES
+		     | OMP_DO_CLAUSES)
+		    & ~(omp_mask (OMP_CLAUSE_ORDERED))
+		    & ~(omp_mask (OMP_CLAUSE_LINEAR)));
 }
 
 
@@ -2257,8 +2300,7 @@  gfc_match_omp_do (void)
 match
 gfc_match_omp_do_simd (void)
 {
-  return match_omp (EXEC_OMP_DO_SIMD, ((OMP_DO_CLAUSES | OMP_SIMD_CLAUSES)
-				       & ~(omp_mask (OMP_CLAUSE_ORDERED))));
+  return match_omp (EXEC_OMP_DO_SIMD, OMP_DO_CLAUSES | OMP_SIMD_CLAUSES);
 }
 
 
@@ -2884,8 +2926,7 @@  match
 gfc_match_omp_parallel_do_simd (void)
 {
   return match_omp (EXEC_OMP_PARALLEL_DO_SIMD,
-		    (OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES | OMP_SIMD_CLAUSES)
-		    & ~(omp_mask (OMP_CLAUSE_ORDERED)));
+		    OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES | OMP_SIMD_CLAUSES);
 }
 
 
@@ -2926,51 +2967,65 @@  gfc_match_omp_single (void)
 
 
 match
-gfc_match_omp_task (void)
+gfc_match_omp_target (void)
 {
-  return match_omp (EXEC_OMP_TASK, OMP_TASK_CLAUSES);
+  return match_omp (EXEC_OMP_TARGET, OMP_TARGET_CLAUSES);
 }
 
 
 match
-gfc_match_omp_taskwait (void)
+gfc_match_omp_target_data (void)
 {
-  if (gfc_match_omp_eos () != MATCH_YES)
-    {
-      gfc_error ("Unexpected junk after TASKWAIT clause at %C");
-      return MATCH_ERROR;
-    }
-  new_st.op = EXEC_OMP_TASKWAIT;
-  new_st.ext.omp_clauses = NULL;
-  return MATCH_YES;
+  return match_omp (EXEC_OMP_TARGET_DATA, OMP_TARGET_DATA_CLAUSES);
 }
 
 
 match
-gfc_match_omp_taskyield (void)
+gfc_match_omp_target_enter_data (void)
 {
-  if (gfc_match_omp_eos () != MATCH_YES)
-    {
-      gfc_error ("Unexpected junk after TASKYIELD clause at %C");
-      return MATCH_ERROR;
-    }
-  new_st.op = EXEC_OMP_TASKYIELD;
-  new_st.ext.omp_clauses = NULL;
-  return MATCH_YES;
+  return match_omp (EXEC_OMP_TARGET_ENTER_DATA, OMP_TARGET_ENTER_DATA_CLAUSES);
 }
 
 
 match
-gfc_match_omp_target (void)
+gfc_match_omp_target_exit_data (void)
 {
-  return match_omp (EXEC_OMP_TARGET, OMP_TARGET_CLAUSES);
+  return match_omp (EXEC_OMP_TARGET_EXIT_DATA, OMP_TARGET_EXIT_DATA_CLAUSES);
 }
 
 
 match
-gfc_match_omp_target_data (void)
+gfc_match_omp_target_parallel (void)
 {
-  return match_omp (EXEC_OMP_TARGET_DATA, OMP_TARGET_DATA_CLAUSES);
+  return match_omp (EXEC_OMP_TARGET_PARALLEL,
+		    (OMP_TARGET_CLAUSES | OMP_PARALLEL_CLAUSES)
+		    & ~(omp_mask (OMP_CLAUSE_COPYIN)));
+}
+
+
+match
+gfc_match_omp_target_parallel_do (void)
+{
+  return match_omp (EXEC_OMP_TARGET_PARALLEL_DO,
+		    (OMP_TARGET_CLAUSES | OMP_PARALLEL_CLAUSES
+		     | OMP_DO_CLAUSES) & ~(omp_mask (OMP_CLAUSE_COPYIN)));
+}
+
+
+match
+gfc_match_omp_target_parallel_do_simd (void)
+{
+  return match_omp (EXEC_OMP_TARGET_PARALLEL_DO_SIMD,
+		    (OMP_TARGET_CLAUSES | OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES
+		     | OMP_SIMD_CLAUSES) & ~(omp_mask (OMP_CLAUSE_COPYIN)));
+}
+
+
+match
+gfc_match_omp_target_simd (void)
+{
+  return match_omp (EXEC_OMP_TARGET_SIMD,
+		    OMP_TARGET_CLAUSES | OMP_SIMD_CLAUSES);
 }
 
 
@@ -2995,9 +3050,11 @@  match
 gfc_match_omp_target_teams_distribute_parallel_do (void)
 {
   return match_omp (EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO,
-		    OMP_TARGET_CLAUSES | OMP_TEAMS_CLAUSES
-		    | OMP_DISTRIBUTE_CLAUSES | OMP_PARALLEL_CLAUSES
-		    | OMP_DO_CLAUSES);
+		    (OMP_TARGET_CLAUSES | OMP_TEAMS_CLAUSES
+		     | OMP_DISTRIBUTE_CLAUSES | OMP_PARALLEL_CLAUSES
+		     | OMP_DO_CLAUSES)
+		    & ~(omp_mask (OMP_CLAUSE_ORDERED))
+		    & ~(omp_mask (OMP_CLAUSE_LINEAR)));
 }
 
 
@@ -3029,6 +3086,57 @@  gfc_match_omp_target_update (void)
 
 
 match
+gfc_match_omp_task (void)
+{
+  return match_omp (EXEC_OMP_TASK, OMP_TASK_CLAUSES);
+}
+
+
+match
+gfc_match_omp_taskloop (void)
+{
+  return match_omp (EXEC_OMP_TASKLOOP, OMP_TASKLOOP_CLAUSES);
+}
+
+
+match
+gfc_match_omp_taskloop_simd (void)
+{
+  return match_omp (EXEC_OMP_TASKLOOP_SIMD,
+		    (OMP_TASKLOOP_CLAUSES | OMP_SIMD_CLAUSES)
+		    & ~(omp_mask (OMP_CLAUSE_REDUCTION)));
+}
+
+
+match
+gfc_match_omp_taskwait (void)
+{
+  if (gfc_match_omp_eos () != MATCH_YES)
+    {
+      gfc_error ("Unexpected junk after TASKWAIT clause at %C");
+      return MATCH_ERROR;
+    }
+  new_st.op = EXEC_OMP_TASKWAIT;
+  new_st.ext.omp_clauses = NULL;
+  return MATCH_YES;
+}
+
+
+match
+gfc_match_omp_taskyield (void)
+{
+  if (gfc_match_omp_eos () != MATCH_YES)
+    {
+      gfc_error ("Unexpected junk after TASKYIELD clause at %C");
+      return MATCH_ERROR;
+    }
+  new_st.op = EXEC_OMP_TASKYIELD;
+  new_st.ext.omp_clauses = NULL;
+  return MATCH_YES;
+}
+
+
+match
 gfc_match_omp_teams (void)
 {
   return match_omp (EXEC_OMP_TEAMS, OMP_TEAMS_CLAUSES);
@@ -3047,8 +3155,10 @@  match
 gfc_match_omp_teams_distribute_parallel_do (void)
 {
   return match_omp (EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO,
-		    OMP_TEAMS_CLAUSES | OMP_DISTRIBUTE_CLAUSES
-		    | OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES);
+		    (OMP_TEAMS_CLAUSES | OMP_DISTRIBUTE_CLAUSES
+		     | OMP_PARALLEL_CLAUSES | OMP_DO_CLAUSES)
+		    & ~(omp_mask (OMP_CLAUSE_ORDERED))
+		    & ~(omp_mask (OMP_CLAUSE_LINEAR)));
 }
 
 
--- gcc/fortran/match.h.jj	2016-05-04 18:37:34.000000000 +0200
+++ gcc/fortran/match.h	2016-05-13 10:56:57.326167994 +0200
@@ -171,6 +171,12 @@  match gfc_match_omp_simd (void);
 match gfc_match_omp_single (void);
 match gfc_match_omp_target (void);
 match gfc_match_omp_target_data (void);
+match gfc_match_omp_target_enter_data (void);
+match gfc_match_omp_target_exit_data (void);
+match gfc_match_omp_target_parallel (void);
+match gfc_match_omp_target_parallel_do (void);
+match gfc_match_omp_target_parallel_do_simd (void);
+match gfc_match_omp_target_simd (void);
 match gfc_match_omp_target_teams (void);
 match gfc_match_omp_target_teams_distribute (void);
 match gfc_match_omp_target_teams_distribute_parallel_do (void);
@@ -179,6 +185,8 @@  match gfc_match_omp_target_teams_distrib
 match gfc_match_omp_target_update (void);
 match gfc_match_omp_task (void);
 match gfc_match_omp_taskgroup (void);
+match gfc_match_omp_taskloop (void);
+match gfc_match_omp_taskloop_simd (void);
 match gfc_match_omp_taskwait (void);
 match gfc_match_omp_taskyield (void);
 match gfc_match_omp_teams (void);
@@ -188,6 +196,7 @@  match gfc_match_omp_teams_distribute_par
 match gfc_match_omp_teams_distribute_simd (void);
 match gfc_match_omp_threadprivate (void);
 match gfc_match_omp_workshare (void);
+match gfc_match_omp_end_critical (void);
 match gfc_match_omp_end_nowait (void);
 match gfc_match_omp_end_single (void);
 
--- gcc/testsuite/gfortran.dg/gomp/target1.f90.jj	2016-05-04 18:31:54.000000000 +0200
+++ gcc/testsuite/gfortran.dg/gomp/target1.f90	2016-05-13 12:17:18.849523825 +0200
@@ -51,15 +51,12 @@  contains
     !$omp & private (p) firstprivate (q) shared (n) reduction (+: r) &
     !$omp & thread_limit (n * 2) dist_schedule (static, 4) collapse (2) &
     !$omp & num_threads (n + 4) proc_bind (spread) lastprivate (s) &
-    !$omp & ordered schedule (static, 8)
+    !$omp & schedule (static, 8)
       do i = 1, 10
         do j = 1, 10
           r = r + 1
           p = q
           call dosomething (a, n, p + q)
-	  !$omp ordered
-	    p = q
-	  !$omp end ordered
 	  s = i * 10 + j
         end do
       end do
@@ -67,16 +64,13 @@  contains
     !$omp & if (n .ne. 6)map (from: n) map (alloc: a(2:o)) default(shared) &
     !$omp & private (p) firstprivate (q) shared (n) reduction (+: r) &
     !$omp & thread_limit (n * 2) dist_schedule (static, 4) num_threads (n + 4) &
-    !$omp & proc_bind (master) lastprivate (s) ordered schedule (static, 8)
+    !$omp & proc_bind (master) lastprivate (s) schedule (static, 8)
       do i = 1, 10
         do j = 1, 10
           r = r + 1
           p = q
           call dosomething (a, n, p + q)
         end do
-        !$omp ordered
-          p = q
-        !$omp end ordered
 	s = i * 10
       end do
     !$omp end target teams distribute parallel do
@@ -167,7 +161,7 @@  contains
     !$omp end target
     !$omp target device (n + 1) if (n .ne. 6)map (from: n) map (alloc: a(2:o))
     !$omp teams distribute parallel do num_teams (n + 4) &
-    !$omp & if (n .ne. 6) default(shared) ordered schedule (static, 8) &
+    !$omp & if (n .ne. 6) default(shared) schedule (static, 8) &
     !$omp & private (p) firstprivate (q) shared (n) reduction (+: r) &
     !$omp & thread_limit (n * 2) dist_schedule (static, 4) collapse (2) &
     !$omp & num_threads (n + 4) proc_bind (spread) lastprivate (s)
@@ -176,9 +170,6 @@  contains
           r = r + 1
           p = q
           call dosomething (a, n, p + q)
-	  !$omp ordered
-	    p = q
-	  !$omp end ordered
 	  s = i * 10 + j
         end do
       end do
@@ -187,16 +178,13 @@  contains
     !$omp teams distribute parallel do num_teams (n + 4)if(n.ne.6)default(shared)&
     !$omp & private (p) firstprivate (q) shared (n) reduction (+: r) &
     !$omp & thread_limit (n * 2) dist_schedule (static, 4) num_threads (n + 4) &
-    !$omp & proc_bind (master) lastprivate (s) ordered schedule (static, 8)
+    !$omp & proc_bind (master) lastprivate (s) schedule (static, 8)
       do i = 1, 10
         do j = 1, 10
           r = r + 1
           p = q
           call dosomething (a, n, p + q)
         end do
-        !$omp ordered
-          p = q
-        !$omp end ordered
 	s = i * 10
       end do
     !$omp end teams distribute parallel do
@@ -285,7 +273,7 @@  contains
     !$omp & map (alloc: a(2:o)) num_teams (n + 4) thread_limit (n * 2) &
     !$omp & default(shared) shared(n) private (p) reduction(+:r)
     !$omp distribute parallel do if (n .ne. 6) default(shared) &
-    !$omp & ordered schedule (static, 8) private (p) firstprivate (q) &
+    !$omp & schedule (static, 8) private (p) firstprivate (q) &
     !$omp & shared(n)reduction(+:r)dist_schedule(static,4)collapse(2)&
     !$omp & num_threads (n + 4) proc_bind (spread) lastprivate (s)
       do i = 1, 10
@@ -293,9 +281,6 @@  contains
           r = r + 1
           p = q
           call dosomething (a, n, p + q)
-	  !$omp ordered
-	    p = q
-	  !$omp end ordered
 	  s = i * 10 + j
         end do
       end do
@@ -306,16 +291,13 @@  contains
     !$omp distribute parallel do if(n.ne.6)default(shared)&
     !$omp & private (p) firstprivate (q) shared (n) reduction (+: r) &
     !$omp & dist_schedule (static, 4) num_threads (n + 4) &
-    !$omp & proc_bind (master) lastprivate (s) ordered schedule (static, 8)
+    !$omp & proc_bind (master) lastprivate (s) schedule (static, 8)
       do i = 1, 10
         do j = 1, 10
           r = r + 1
           p = q
           call dosomething (a, n, p + q)
         end do
-        !$omp ordered
-          p = q
-        !$omp end ordered
 	s = i * 10
       end do
     !$omp end distribute parallel do
@@ -418,7 +400,7 @@  contains
     !$omp & map (alloc: a(2:o)) num_teams (n + 4) thread_limit (n * 2) &
     !$omp & default(shared) shared(n) private (p) reduction(+:r)
     !$omp distribute parallel do if (n .ne. 6) default(shared) &
-    !$omp & ordered schedule (static, 8) private (p) firstprivate (q) &
+    !$omp & schedule (static, 8) private (p) firstprivate (q) &
     !$omp & shared(n)reduction(+:r)dist_schedule(static,4)collapse(2)&
     !$omp & num_threads (n + 4) proc_bind (spread) lastprivate (s)
       do i = 1, 10
@@ -426,9 +408,6 @@  contains
           r = r + 1
           p = q
           call dosomething (a, n, p + q)
-	  !$omp ordered
-	    p = q
-	  !$omp end ordered
 	  s = i * 10 + j
         end do
       end do
@@ -439,16 +418,13 @@  contains
     !$omp distribute parallel do if(n.ne.6)default(shared)&
     !$omp & private (p) firstprivate (q) shared (n) reduction (+: r) &
     !$omp & dist_schedule (static, 4) num_threads (n + 4) &
-    !$omp & proc_bind (master) lastprivate (s) ordered schedule (static, 8)
+    !$omp & proc_bind (master) lastprivate (s) schedule (static, 8)
       do i = 1, 10
         do j = 1, 10
           r = r + 1
           p = q
           call dosomething (a, n, p + q)
         end do
-        !$omp ordered
-          p = q
-        !$omp end ordered
 	s = i * 10
       end do
     !$omp end distribute parallel do