]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
OpenMP: uses_allocators with ';'-separated list
authorTobias Burnus <tburnus@baylibre.com>
Fri, 19 Dec 2025 11:07:58 +0000 (12:07 +0100)
committerTobias Burnus <tburnus@baylibre.com>
Fri, 19 Dec 2025 11:07:58 +0000 (12:07 +0100)
OpenMP 6.0 has the following wording for the uses_allocators clause:
"More than one clause-argument-specification may be specified";
this permits ';' lists. While that's pointless for predefined
allocators, for user-defined allocators it saves redundant
') uses_allocators(' by permitting:
  uses_allocators( traits(t1): alloc1 ; traits(t2): alloc2 )

Additionally, the order in the tree dump has been changed to
place the modifiers before the allocator variable, matching
the input syntax.

gcc/c/ChangeLog:

* c-parser.cc (c_parser_omp_clause_uses_allocators): Accept
multiple clause-argument-specifications separated by ';'.

gcc/cp/ChangeLog:

* parser.cc (cp_parser_omp_clause_uses_allocators): Accept
multiple clause-argument-specifications separated by ';'.

gcc/fortran/ChangeLog:

* openmp.cc (gfc_match_omp_clause_uses_allocators): Accept
multiple clause-argument-specifications separated by ';'.

gcc/ChangeLog:

* tree-pretty-print.cc (dump_omp_clause): For uses_allocators,
print modifier before allocator variable.

libgomp/ChangeLog:

* testsuite/libgomp.fortran/uses_allocators-7.f90: Add ';' test.

gcc/testsuite/ChangeLog:

* c-c++-common/gomp/uses_allocators-8.c: New test.

gcc/c/c-parser.cc
gcc/cp/parser.cc
gcc/fortran/openmp.cc
gcc/testsuite/c-c++-common/gomp/uses_allocators-8.c [new file with mode: 0644]
gcc/tree-pretty-print.cc
libgomp/testsuite/libgomp.fortran/uses_allocators-7.f90

index e39429afbb5c76a1e4666711471f75279010545f..8065d3000e6127097949fcc133fcf6f9be6a9b98 100644 (file)
@@ -19577,11 +19577,16 @@ c_parser_omp_clause_allocate (c_parser *parser, tree list)
    allocator ( traits-array )
    allocator ( traits-array ) , allocator-list
 
+   Deprecated in 5.2, removed in 6.0: 'allocator(trait-array)' syntax.
+
    OpenMP 5.2:
 
    uses_allocators ( modifier : allocator-list )
    uses_allocators ( modifier , modifier : allocator-list )
 
+   OpenMP 6.0:
+   uses_allocators ( [modifier-list :] allocator-list [; ...] )
+
    modifier:
    traits ( traits-array )
    memspace ( mem-space-handle )  */
@@ -19595,6 +19600,8 @@ c_parser_omp_clause_uses_allocators (c_parser *parser, tree list)
   if (!parens.require_open (parser))
     return list;
 
+parse_next:
+
   bool has_modifiers = false;
   bool seen_allocators = false;
   tree memspace_expr = NULL_TREE;
@@ -19790,6 +19797,12 @@ c_parser_omp_clause_uses_allocators (c_parser *parser, tree list)
        break;
     }
 
+  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
+    {
+      c_parser_consume_token (parser);
+      goto parse_next;
+    }
+
  end:
   parens.skip_until_found_close (parser);
   return nl;
index e106583c4b8bf0b9a7789f7956bbbf61e063db11..4685a9ab80fae8bbfe5fb60bb38e091557c605fc 100644 (file)
@@ -42815,11 +42815,16 @@ cp_parser_omp_clause_allocate (cp_parser *parser, tree list)
    allocator ( traits-array )
    allocator ( traits-array ) , allocator-list
 
+   Deprecated in 5.2, removed in 6.0: 'allocator(trait-array)' syntax.
+
    OpenMP 5.2:
 
    uses_allocators ( modifier : allocator-list )
    uses_allocators ( modifier , modifier : allocator-list )
 
+   OpenMP 6.0:
+   uses_allocators ( [modifier-list :] allocator-list [; ...] )
+
    modifier:
    traits ( traits-array )
    memspace ( mem-space-handle )  */
@@ -42834,6 +42839,8 @@ cp_parser_omp_clause_uses_allocators (cp_parser *parser, tree list)
   if (!parens.require_open (parser))
     return list;
 
+parse_next:
+
   bool has_modifiers = false;
   bool seen_allocators = false;
   tree memspace_expr = NULL_TREE;
@@ -42988,9 +42995,16 @@ cp_parser_omp_clause_uses_allocators (cp_parser *parser, tree list)
        break;
     }
 
+  if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+    {
+      cp_lexer_consume_token (parser->lexer);
+      goto parse_next;
+    }
+
   if (!parens.require_close (parser))
     goto end;
   return nl;
+
  end:
   cp_parser_skip_to_closing_parenthesis (parser,
                                         /*recovering=*/true,
index a7a76694c2c72affac9e846336ef4302051da83f..76c601952a7068db6c22e9d62e8e2f326329f35e 100644 (file)
@@ -1795,9 +1795,14 @@ omp_verify_merge_absent_contains (gfc_statement st, gfc_omp_assumptions *check,
      predefined-allocator
      variable ( traits-array )
 
+   OpenMP 5.2 deprecated, 6.0 deleted: 'variable ( traits-array )'
+
    OpenMP 5.2:
    uses_allocators ( [modifier-list :] allocator-list )
 
+   OpenMP 6.0:
+   uses_allocators ( [modifier-list :] allocator-list [; ...])
+
    allocator:
      variable or predefined-allocator
    modifier:
@@ -1807,6 +1812,7 @@ omp_verify_merge_absent_contains (gfc_statement st, gfc_omp_assumptions *check,
 static match
 gfc_match_omp_clause_uses_allocators (gfc_omp_clauses *c)
 {
+parse_next:
   gfc_symbol *memspace_sym = NULL;
   gfc_symbol *traits_sym = NULL;
   gfc_omp_namelist *head = NULL;
@@ -1878,11 +1884,17 @@ gfc_match_omp_clause_uses_allocators (gfc_omp_clauses *c)
          p->u.memspace_sym = memspace_sym;
          p->u2.traits_sym = traits_sym;
        }
-      if (gfc_match (", ") == MATCH_YES)
-       continue;
-      if (gfc_match (") ") == MATCH_YES)
+      gfc_gobble_whitespace ();
+      const char c = gfc_peek_ascii_char ();
+      if (c == ';' || c == ')')
        break;
-      goto error;
+      if (c != ',')
+       {
+         gfc_error ("Expected %<,%>, %<)%> or %<;%> at %C");
+         goto error;
+       }
+      gfc_match_char (',');
+      gfc_gobble_whitespace ();
     } while (true);
 
   list = &c->lists[OMP_LIST_USES_ALLOCATORS];
@@ -1890,6 +1902,10 @@ gfc_match_omp_clause_uses_allocators (gfc_omp_clauses *c)
     list = &(*list)->next;
   *list = head;
 
+  if (gfc_match_char (';') == MATCH_YES)
+    goto parse_next;
+
+  gfc_match_char (')');
   return MATCH_YES;
 
 error:
diff --git a/gcc/testsuite/c-c++-common/gomp/uses_allocators-8.c b/gcc/testsuite/c-c++-common/gomp/uses_allocators-8.c
new file mode 100644 (file)
index 0000000..642b6b9
--- /dev/null
@@ -0,0 +1,59 @@
+// { dg-do compile }
+
+//#include <omp.h>
+
+typedef __UINTPTR_TYPE__ omp_uintptr_t;
+
+#if __cplusplus >= 201103L
+# define __GOMP_UINTPTR_T_ENUM : omp_uintptr_t
+#else
+# define __GOMP_UINTPTR_T_ENUM
+#endif
+
+typedef enum omp_memspace_handle_t __GOMP_UINTPTR_T_ENUM
+{
+  omp_default_mem_space = 0,
+  omp_large_cap_mem_space = 1,
+  omp_const_mem_space = 2,
+  omp_high_bw_mem_space = 3,
+  omp_low_lat_mem_space = 4,
+  ompx_gnu_managed_mem_space = 200,
+  __omp_memspace_handle_t_max__ = __UINTPTR_MAX__
+} omp_memspace_handle_t;
+
+typedef enum omp_allocator_handle_t __GOMP_UINTPTR_T_ENUM
+{
+  omp_null_allocator = 0,
+  omp_default_mem_alloc = 1,
+  omp_large_cap_mem_alloc = 2,
+  omp_const_mem_alloc = 3,
+  omp_high_bw_mem_alloc = 4,
+  omp_low_lat_mem_alloc = 5,
+  omp_cgroup_mem_alloc = 6,
+  omp_pteam_mem_alloc = 7,
+  omp_thread_mem_alloc = 8,
+  ompx_gnu_pinned_mem_alloc = 200,
+  ompx_gnu_managed_mem_alloc = 201,
+  __omp_allocator_handle_t_max__ = __UINTPTR_MAX__
+} omp_allocator_handle_t;
+
+typedef struct omp_alloctrait_t
+{
+//  omp_alloctrait_key_t key;
+//  omp_uintptr_t value;
+} omp_alloctrait_t;
+
+
+void f()
+{
+ omp_allocator_handle_t my, my2, my3, my4;
+const omp_alloctrait_t t[] = {};
+const omp_alloctrait_t t2[] = {};
+ #pragma omp target uses_allocators(traits(t), memspace(omp_high_bw_mem_space) : my; omp_default_mem_alloc, omp_null_allocator; my2; traits(t2) : my3; memspace(omp_large_cap_mem_space) : my4)
+   ;
+}
+
+// { dg-final { scan-tree-dump "#pragma omp target uses_allocators\\(memspace\\(1\\), traits\\(\\) : my4\\) uses_allocators\\(memspace\\(\\), traits\\(t2\\) : my3\\) uses_allocators\\(memspace\\(\\), traits\\(\\) : my2\\) uses_allocators\\(memspace\\(3\\), traits\\(t\\) : my\\)" "original" } }
+
+
+// { dg-message "sorry, unimplemented: 'uses_allocators' clause" "" { target *-*-* } 52 }
index 15e7ead32e1b4543b76b5e3760fe2bb2964a0e2a..54bf79800925743124c7123897a6c7840c2e4909 100644 (file)
@@ -908,16 +908,15 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
       break;
 
     case OMP_CLAUSE_USES_ALLOCATORS:
-      pp_string (pp, "uses_allocators(");
-      dump_generic_node (pp, OMP_CLAUSE_USES_ALLOCATORS_ALLOCATOR (clause),
-                        spc, flags, false);
-      pp_string (pp, ": memspace(");
+      pp_string (pp, "uses_allocators(memspace(");
       dump_generic_node (pp, OMP_CLAUSE_USES_ALLOCATORS_MEMSPACE (clause),
                         spc, flags, false);
       pp_string (pp, "), traits(");
       dump_generic_node (pp, OMP_CLAUSE_USES_ALLOCATORS_TRAITS (clause),
                         spc, flags, false);
-      pp_right_paren (pp);
+      pp_string (pp, ") : ");
+      dump_generic_node (pp, OMP_CLAUSE_USES_ALLOCATORS_ALLOCATOR (clause),
+                        spc, flags, false);
       pp_right_paren (pp);
       break;
 
index e5376e466666375bd832b093217140c40b592a32..32a901a8e02f907a1d59092ad5654d02cde8dc8c 100644 (file)
@@ -6,8 +6,15 @@ program main
   implicit none (type, external)
   integer :: x, xbuf(10)
   integer(c_intptr_t) :: iptr
-  integer(omp_allocator_handle_kind) :: my_alloc
+  integer(omp_allocator_handle_kind) :: my_alloc, my, my2, my3, my4
   type(omp_alloctrait), parameter :: trait(*) = [omp_alloctrait(omp_atk_alignment, 128)]
+  type(omp_alloctrait), parameter :: t(*) = [omp_alloctrait:: ]
+  type(omp_alloctrait), parameter :: t2(*) = [omp_alloctrait:: ]
+
+  ! FIXME - improve check that that ';' is handled
+  !$omp target uses_allocators(traits(t), memspace(omp_high_bw_mem_space) : my; omp_default_mem_alloc, omp_null_allocator; my2; traits(t2) : my3; memspace(omp_large_cap_mem_space) : my4)
+  block
+  end block
 
   !$omp target uses_allocators(omp_low_lat_mem_alloc) map(tofrom: x, xbuf) defaultmap(none)
     !$omp parallel allocate(allocator(omp_low_lat_mem_alloc), align(128): x, xbuf) if(.false.) firstprivate(x, xbuf)
@@ -50,9 +57,12 @@ end
 ! FIXME ENABLE: 'dg FIXME final' -> 'dg-final'
 ! { dg  FIXME  final { scan-tree-dump-times "#pragma omp target .*private\\(my_alloc\\).*uses_allocators\\(my_alloc: memspace\\(\\), traits\\(trait\\)\\)" 1 "gimple" } }
 ! { dg  FIXME  final { scan-tree-dump-times "#pragma omp target .*private\\(my_alloc\\).*uses_allocators\\(my_alloc: memspace\\(\\), traits\\(\\)\\)" 1 "gimple" } }
+! { dg  FIXME  final { scan-tree-dump "#pragma omp target uses_allocators\\(memspace\\(1\\), traits\\(\\) : my4\\) uses_allocators\\(memspace\\(\\), traits\\(t2\\) : my3\\) uses_allocators\\(memspace\\(\\), traits\\(\\) : my2\\) uses_allocators\\(memspace\\(3\\), traits\\(t\\) : my\\)" 1 "original" } }
+
 
 ! FIXME ENABLE code above for "gimple" once it has been implemented:
-! { dg-message "sorry, unimplemented: 'uses_allocators' clause with traits and memory spaces" "" { target *-*-* } 23 }
-! { dg-message "sorry, unimplemented: 'uses_allocators' clause with traits and memory spaces" "" { target *-*-* } 36 }
-! { dg-bogus "'my_alloc' not specified in enclosing 'target'" "bogus issue because clause is ignored" { xfail *-*-* } 24 }
-! { dg-bogus "'my_alloc' not specified in enclosing 'target'" "bogus issue because clause is ignored" { xfail *-*-* } 37 }
+! { dg-message "sorry, unimplemented: 'uses_allocators' clause with traits and memory spaces" "" { target *-*-* } 15 }
+! { dg-message "sorry, unimplemented: 'uses_allocators' clause with traits and memory spaces" "" { target *-*-* } 30 }
+! { dg-message "sorry, unimplemented: 'uses_allocators' clause with traits and memory spaces" "" { target *-*-* } 43 }
+! { dg-bogus "'my_alloc' not specified in enclosing 'target'" "bogus issue because clause is ignored" { xfail *-*-* } 31 }
+! { dg-bogus "'my_alloc' not specified in enclosing 'target'" "bogus issue because clause is ignored" { xfail *-*-* } 44 }