diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index ffb6eda5490..d9fda21413d 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -72,6 +72,7 @@ along with GCC; see the file COPYING3.  If not see
 
 //#define NOISY_TOPOSORT
 //#define NOISY_SIBLING_LISTS
+//#define NOISY_TAXONOMY
 
 /* Hash set of poisoned variables in a bind expr.  */
 static hash_set<tree> *asan_poisoned_variables = NULL;
@@ -9010,6 +9011,326 @@ omp_gather_mapping_groups (tree *list_p)
     }
 }
 
+#ifdef NOISY_TAXONOMY
+
+static void
+omp_mapping_group_taxonomy (vec<omp_mapping_group> *groups)
+{
+  int num = 0;
+
+  for (auto &it : *groups)
+    {
+      tree node, grp_start = *it.grp_start, grp_end = it.grp_end;
+      gomp_map_kind kind0 = OMP_CLAUSE_MAP_KIND (grp_start), kind1, kind2,
+		    kind3;
+      int count = 1;
+      node = grp_start;
+      if (node != grp_end)
+	{
+	  node = OMP_CLAUSE_CHAIN (node);
+	  kind1 = OMP_CLAUSE_MAP_KIND (node);
+	  count++;
+	  if (node != grp_end)
+	    {
+	      node = OMP_CLAUSE_CHAIN (node);
+	      kind2 = OMP_CLAUSE_MAP_KIND (node);
+	      count++;
+	      if (node != grp_end)
+		{
+		  node = OMP_CLAUSE_CHAIN (node);
+		  kind3 = OMP_CLAUSE_MAP_KIND (node);
+		  count++;
+		  gcc_assert (node == grp_end);
+		}
+	    }
+	}
+
+      fprintf (stderr, "group %d: ", num);
+
+      switch (count)
+	{
+	case 1:
+	  if (kind0 == GOMP_MAP_TO
+	      || kind0 == GOMP_MAP_FROM
+	      || kind0 == GOMP_MAP_TOFROM)
+	    fprintf (stderr, "scalar to/from\n");
+	  else if (kind0 == GOMP_MAP_ALLOC)
+	    fprintf (stderr, "alloc\n");
+	  else if (kind0 == GOMP_MAP_POINTER)
+	    fprintf (stderr, "pointer (by itself)\n");
+	  else if (kind0 == GOMP_MAP_TO_PSET)
+	    fprintf (stderr, "map-to-pset (by itself)\n");
+	  else if (kind0 == GOMP_MAP_FORCE_PRESENT)
+	    fprintf (stderr, "force present\n");
+	  else if (kind0 == GOMP_MAP_DELETE)
+	    fprintf (stderr, "delete\n");
+	  else if (kind0 == GOMP_MAP_FORCE_DEVICEPTR)
+	    fprintf (stderr, "force deviceptr\n");
+	  else if (kind0 == GOMP_MAP_DEVICE_RESIDENT)
+	    fprintf (stderr, "device resident\n");
+	  else if (kind0 == GOMP_MAP_LINK)
+	    fprintf (stderr, "link\n");
+	  else if (kind0 == GOMP_MAP_IF_PRESENT)
+	    fprintf (stderr, "if present\n");
+	  else if (kind0 == GOMP_MAP_FIRSTPRIVATE)
+	    fprintf (stderr, "firstprivate (by itself)\n");
+	  else if (kind0 == GOMP_MAP_FIRSTPRIVATE_INT)
+	    fprintf (stderr, "firstprivate_int (by itself)\n");
+	  else if (kind0 == GOMP_MAP_USE_DEVICE_PTR)
+	    fprintf (stderr, "use device ptr\n");
+	  else if (kind0 == GOMP_MAP_ZERO_LEN_ARRAY_SECTION)
+	    fprintf (stderr, "zero-length array section (by itself)\n");
+	  else if (kind0 == GOMP_MAP_FORCE_ALLOC)
+	    fprintf (stderr, "force alloc\n");
+	  else if (kind0 == GOMP_MAP_FORCE_TO
+		   || kind0 == GOMP_MAP_FORCE_FROM
+		   || kind0 == GOMP_MAP_FORCE_TOFROM)
+	    fprintf (stderr, "force to/from (scalar)\n");
+	  else if (kind0 == GOMP_MAP_USE_DEVICE_PTR_IF_PRESENT)
+	    fprintf (stderr, "use device ptr if present\n");
+	  else if (kind0 == GOMP_MAP_ALWAYS_TO
+		   || kind0 == GOMP_MAP_ALWAYS_FROM
+		   || kind0 == GOMP_MAP_ALWAYS_TOFROM)
+	    fprintf (stderr, "always to/from (scalar)\n");
+	  else if (kind0 == GOMP_MAP_STRUCT)
+	    fprintf (stderr, "struct\n");
+	  else if (kind0 == GOMP_MAP_ALWAYS_POINTER)
+	    fprintf (stderr, "always pointer (by itself)\n");
+	  else if (kind0 == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION)
+	    fprintf (stderr, "ptr to 0-length array section (by itself)\n");
+	  else if (kind0 == GOMP_MAP_RELEASE)
+	    fprintf (stderr, "release\n");
+	  else if (kind0 == GOMP_MAP_ATTACH)
+	    fprintf (stderr, "attach\n");
+	  else if (kind0 == GOMP_MAP_DETACH)
+	    fprintf (stderr, "detach\n");
+	  else if (kind0 == GOMP_MAP_FORCE_DETACH)
+	    fprintf (stderr, "force detach\n");
+	  else if (kind0 == GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION)
+	    fprintf (stderr, "attach 0-length array section\n");
+	  else if (kind0 == GOMP_MAP_FIRSTPRIVATE_POINTER)
+	    fprintf (stderr, "firstprivate ptr (by itself)\n");
+	  else if (kind0 == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
+	    fprintf (stderr, "firstprivate ref (by itself)\n");
+	  else if (kind0 == GOMP_MAP_ATTACH_DETACH)
+	    fprintf (stderr, "attach/detach (by itself)\n");
+	  else
+	    fprintf (stderr, "unknown code %d\n", (int) kind0);
+	  break;
+
+	case 2:
+	  if (kind0 == GOMP_MAP_TO
+	      || kind0 == GOMP_MAP_FROM
+	      || kind0 == GOMP_MAP_TOFROM)
+	    {
+	      if (kind1 == GOMP_MAP_POINTER)
+		fprintf (stderr, "to/from, pointer\n");
+	      else if (kind1 == GOMP_MAP_ALWAYS_POINTER)
+		fprintf (stderr, "to/from, always pointer\n");
+	      else if (kind1 == GOMP_MAP_ATTACH_DETACH)
+		fprintf (stderr, "to/from, attach/detach\n");
+	      else if (kind1 == GOMP_MAP_FIRSTPRIVATE_POINTER)
+		fprintf (stderr, "to/from, firstprivate pointer\n");
+	      else if (kind1 == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
+		fprintf (stderr, "to/from, firstprivate reference\n");
+	      else
+		fprintf (stderr, "to/from, unknown code %d\n", (int) kind1);
+	    }
+	  else if (kind0 == GOMP_MAP_ALWAYS_FROM
+		   || kind0 == GOMP_MAP_ALWAYS_TO
+		   || kind0 == GOMP_MAP_ALWAYS_TOFROM)
+	    {
+	      if (kind1 == GOMP_MAP_FIRSTPRIVATE_POINTER)
+		fprintf (stderr, "always to/from, firstprivate pointer\n");
+	      else if (kind1 == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
+		fprintf (stderr, "always to/from, firstprivate reference\n");
+	      else if (kind1 == GOMP_MAP_ATTACH_DETACH)
+		fprintf (stderr, "always to/from, attach/detach\n");
+	      else if (kind1 == GOMP_MAP_ALWAYS_POINTER)
+		fprintf (stderr, "always to/from, always pointer\n");
+	      else
+		fprintf (stderr, "always to/from, unknown code %d\n",
+			 (int) kind1);
+	    }
+	  else if (kind0 == GOMP_MAP_FORCE_TO
+		   || kind0 == GOMP_MAP_FORCE_FROM
+		   || kind0 == GOMP_MAP_FORCE_TOFROM)
+	    {
+	      if (kind1 == GOMP_MAP_POINTER)
+		fprintf (stderr, "force to/from, pointer\n");
+	      else
+		fprintf (stderr, "force to/from, unknown code %d\n",
+			 (int) kind1);
+	    }
+	  else if (kind0 == GOMP_MAP_FORCE_PRESENT)
+	    {
+	      if (kind1 == GOMP_MAP_POINTER)
+		fprintf (stderr, "force present, pointer\n");
+	      else if (kind1 == GOMP_MAP_FIRSTPRIVATE_POINTER)
+		fprintf (stderr, "force present, firstprivate pointer\n");
+	      else
+		fprintf (stderr, "force present, unknown code %d\n",
+			 (int) kind1);
+	    }
+	  else if (kind0 == GOMP_MAP_ALLOC)
+	    {
+	      if (kind1 == GOMP_MAP_POINTER)
+		fprintf (stderr, "alloc, pointer\n");
+	      else if (kind1 == GOMP_MAP_ALWAYS_POINTER)
+		fprintf (stderr, "alloc, always pointer\n");
+	      else if (kind1 == GOMP_MAP_ATTACH_DETACH)
+		fprintf (stderr, "alloc, attach/detach\n");
+	      else if (kind1 == GOMP_MAP_FIRSTPRIVATE_POINTER)
+		fprintf (stderr, "alloc, firstprivate pointer\n");
+	      else if (kind1 == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
+		fprintf (stderr, "alloc, firstprivate reference\n");
+	      else
+		fprintf (stderr, "alloc, unknown code %d\n", (int) kind1);
+	    }
+	  else if (kind0 == GOMP_MAP_RELEASE)
+	    {
+	      if (kind1 == GOMP_MAP_FIRSTPRIVATE_REFERENCE)
+		fprintf (stderr, "release, firstprivate reference\n");
+	      else if (kind1 == GOMP_MAP_ATTACH_DETACH)
+		fprintf (stderr, "release, attach/detach\n");
+	      else if (kind1 == GOMP_MAP_ALWAYS_POINTER)
+		fprintf (stderr, "release, always pointer\n");
+	      else if (kind1 == GOMP_MAP_POINTER)
+		fprintf (stderr, "release, pointer\n");
+	      else
+		fprintf (stderr, "release, unknown code %d\n", (int) kind1);
+	    }
+	  else if (kind0 == GOMP_MAP_DELETE)
+	    {
+	      if (kind1 == GOMP_MAP_ATTACH_DETACH)
+		fprintf (stderr, "delete, attach/detach\n");
+	      else
+		fprintf (stderr, "delete, unknown code %d\n", (int) kind1);
+	    }
+	  else if (kind0 == GOMP_MAP_TO_PSET)
+	    {
+	      if (kind1 == GOMP_MAP_ATTACH)
+		fprintf (stderr, "pset, attach\n");
+	      else if (kind1 == GOMP_MAP_DETACH)
+		fprintf (stderr, "pset, detach\n");
+	      else
+		fprintf (stderr, "pset, unknown code %d\n", (int) kind1);
+	    }
+	  else
+	    fprintf (stderr, "unknown code %d, unknown code %d\n",
+		     (int) kind0, (int) kind1);
+	  break;
+
+	case 3:
+	  if (kind0 == GOMP_MAP_TO
+	      || kind0 == GOMP_MAP_FROM
+	      || kind0 == GOMP_MAP_TOFROM)
+	    {
+	      if (kind1 == GOMP_MAP_POINTER
+		  && kind2 == GOMP_MAP_POINTER)
+		fprintf (stderr, "to/from, pointer, pointer\n");
+	      else if (kind1 == GOMP_MAP_ALWAYS_POINTER
+		       && kind2 == GOMP_MAP_ALWAYS_POINTER)
+		fprintf (stderr, "to/from, always-pointer, always-pointer\n");
+	      else if (kind1 == GOMP_MAP_TO_PSET
+		       && kind2 == GOMP_MAP_POINTER)
+		fprintf (stderr, "to/from, pset, pointer\n");
+	      else if (kind1 == GOMP_MAP_TO_PSET
+		       && kind2 == GOMP_MAP_ALWAYS_POINTER)
+		fprintf (stderr, "to/from, pset, always-pointer\n");
+	      else if (kind1 == GOMP_MAP_TO_PSET
+		       && kind2 == GOMP_MAP_ATTACH_DETACH)
+		fprintf (stderr, "to/from, pset, attach/detach\n");
+	      else if (kind1 == GOMP_MAP_POINTER
+		       && kind2 == GOMP_MAP_ATTACH_DETACH)
+		fprintf (stderr, "to/from, pointer, attach/detach\n");
+	      else if (kind1 == GOMP_MAP_ALWAYS_POINTER
+		       && kind2 == GOMP_MAP_ATTACH_DETACH)
+		fprintf (stderr, "to/from, always-pointer, attach/detach\n");
+	      else
+		fprintf (stderr, "to/from, unknown code %d, unknown code %d\n",
+			 (int) kind1, (int) kind2);
+	    }
+	  else if (kind0 == GOMP_MAP_FORCE_TO
+		   || kind0 == GOMP_MAP_FORCE_FROM
+		   || kind0 == GOMP_MAP_FORCE_TOFROM)
+	    {
+	      if (kind1 == GOMP_MAP_TO_PSET
+		  && kind2 == GOMP_MAP_POINTER)
+		fprintf (stderr, "force to/from, pset, pointer\n");
+	      else
+		fprintf (stderr, "force to/from, unknown code %d, "
+			 "unknown code %d\n", (int) kind1, (int) kind2);
+	    }
+	  else if (kind0 == GOMP_MAP_ALLOC)
+	    {
+	      if (kind1 == GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION
+		  && kind2 == GOMP_MAP_ATTACH)
+		fprintf (stderr, "alloc, pointer to z-l-a-s, attach\n");
+	      else if (kind1 == GOMP_MAP_TO_PSET
+		       && kind2 == GOMP_MAP_POINTER)
+		fprintf (stderr, "alloc, pset, pointer\n");
+	      else if (kind1 == GOMP_MAP_TO_PSET
+		       && kind2 == GOMP_MAP_ALWAYS_POINTER)
+		fprintf (stderr, "alloc, pset, always-pointer\n");
+	      else
+		fprintf (stderr, "alloc, unknown code %d, unknown code %d\n",
+			 (int) kind1, (int) kind2);
+	    }
+	  else if (kind0 == GOMP_MAP_DELETE)
+	    {
+	      if (kind1 == GOMP_MAP_TO_PSET
+		  || kind1 == GOMP_MAP_POINTER)
+		fprintf (stderr, "delete, pset, pointer\n");
+	      else
+		fprintf (stderr, "delete, unknown code %d, unknown code %d\n",
+			 (int) kind1, (int) kind2);
+	    }
+	  else
+	    fprintf (stderr, "unknown code %d, unknown code %d, "
+		     "unknown code %d\n", (int) kind0, (int) kind1,
+		     (int) kind2);
+	  break;
+
+	case 4:
+	  if (kind0 == GOMP_MAP_TO
+	      || kind0 == GOMP_MAP_FROM
+	      || kind0 == GOMP_MAP_TOFROM)
+	    {
+	      if (kind1 == GOMP_MAP_TO_PSET
+		  && kind2 == GOMP_MAP_POINTER
+		  && kind3 == GOMP_MAP_POINTER)
+		fprintf (stderr, "to/from, pset, pointer, pointer\n");
+	      else if (kind1 == GOMP_MAP_TO_PSET
+		       && kind2 == GOMP_MAP_ALWAYS_POINTER
+		       && kind3 == GOMP_MAP_POINTER)
+		fprintf (stderr, "to/from, pset, always pointer, pointer\n");
+	      else
+		fprintf (stderr, "to/from, unknown code %d, unknown code %d, "
+			 "unknown code %d\n", (int) kind1, (int) kind2,
+			 (int) kind3);
+	    }
+	  else
+	    fprintf (stderr, "unknown code %d, unknown code %d, "
+		     "unknown code %d, unknown code %d\n", (int) kind0,
+		     (int) kind1, (int) kind2, (int) kind3);
+	  break;
+
+	default:
+	  gcc_unreachable ();
+	}
+
+      tree tmp = OMP_CLAUSE_CHAIN (grp_end);
+      OMP_CLAUSE_CHAIN (grp_end) = NULL_TREE;
+      debug_generic_expr (grp_start);
+      OMP_CLAUSE_CHAIN (grp_end) = tmp;
+
+      num++;
+    }
+}
+
+#endif
+
 /* A pointer mapping group GRP may define a block of memory starting at some
    base address, and maybe also define a firstprivate pointer or firstprivate
    reference that points to that block.  The return value is a node containing
@@ -10493,6 +10814,9 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
       groups = omp_gather_mapping_groups (list_p);
       if (groups)
 	{
+#ifdef NOISY_TAXONOMY
+	  omp_mapping_group_taxonomy (groups);
+#endif
 	  hash_map<tree_operand_hash, omp_mapping_group *> *grpmap;
 	  grpmap = omp_index_mapping_groups (groups);
 
@@ -10556,6 +10880,9 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
       groups = omp_gather_mapping_groups (list_p);
       if (groups)
 	{
+#ifdef NOISY_TAXONOMY
+	  omp_mapping_group_taxonomy (groups);
+#endif
 	  hash_map<tree_operand_hash, omp_mapping_group *> *grpmap;
 	  grpmap = omp_index_mapping_groups (groups);
 
