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 ) */
if (!parens.require_open (parser))
return list;
+parse_next:
+
bool has_modifiers = false;
bool seen_allocators = false;
tree memspace_expr = NULL_TREE;
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;
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 ) */
if (!parens.require_open (parser))
return list;
+parse_next:
+
bool has_modifiers = false;
bool seen_allocators = false;
tree memspace_expr = NULL_TREE;
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,
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:
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;
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];
list = &(*list)->next;
*list = head;
+ if (gfc_match_char (';') == MATCH_YES)
+ goto parse_next;
+
+ gfc_match_char (')');
return MATCH_YES;
error:
--- /dev/null
+// { 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 }
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;
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)
! 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 }