From: Andrew Stubbs <a...@codesourcery.com> Ensure that "requires unified_shared_memory" plays nicely with the -foffload-memory options, and that enabling the option has the same effect as enabling USM in the code.
Also adds some testcases. gcc/c/ChangeLog: * c-parser.cc (c_parser_omp_target): Add OMP_REQUIRES_UNIFIED_SHARED_MEMORY to omp_requires_mask, if needed. (c_parser_omp_requires): Check requires doesn't conflict with -foffload-memory. gcc/cp/ChangeLog: * parser.cc (cp_parser_omp_target): Add OMP_REQUIRES_UNIFIED_SHARED_MEMORY to omp_requires_mask, if needed. (cp_parser_omp_requires): Check requires doesn't conflict with -foffload-memory. gcc/fortran/ChangeLog: * openmp.cc (gfc_match_omp_requires): Check requires doesn't conflict with -foffload-memory. * parse.cc (gfc_parse_file): Check -foffload-memory option when setting omp_requires_mask. libgomp/ChangeLog: * testsuite/libgomp.fortran/usm-1.f90: New test. gcc/testsuite/ChangeLog: * c-c++-common/gomp/usm-1.c: New test. * gfortran.dg/gomp/usm-1.f90: New test. --- gcc/c/c-parser.cc | 20 ++++++++++++--- gcc/cp/parser.cc | 20 ++++++++++++--- gcc/fortran/openmp.cc | 6 +++++ gcc/fortran/parse.cc | 3 ++- gcc/testsuite/c-c++-common/gomp/usm-1.c | 4 +++ gcc/testsuite/gfortran.dg/gomp/usm-1.f90 | 6 +++++ libgomp/testsuite/libgomp.fortran/usm-1.f90 | 28 +++++++++++++++++++++ 7 files changed, 80 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/gomp/usm-1.c create mode 100644 gcc/testsuite/gfortran.dg/gomp/usm-1.f90 create mode 100644 libgomp/testsuite/libgomp.fortran/usm-1.f90 diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc index 00f8bf4376e..3d8c40185cd 100644 --- a/gcc/c/c-parser.cc +++ b/gcc/c/c-parser.cc @@ -24223,8 +24223,14 @@ c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p) } if (flag_openmp) - omp_requires_mask - = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED); + { + omp_requires_mask + = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED); + if (flag_offload_memory == OFFLOAD_MEMORY_UNIFIED) + omp_requires_mask + = (enum omp_requires) (omp_requires_mask + | OMP_REQUIRES_UNIFIED_SHARED_MEMORY); + } if (c_parser_next_token_is (parser, CPP_NAME)) { @@ -25871,7 +25877,15 @@ c_parser_omp_requires (c_parser *parser) if (!strcmp (p, "unified_address")) this_req = OMP_REQUIRES_UNIFIED_ADDRESS; else if (!strcmp (p, "unified_shared_memory")) - this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY; + { + this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY; + + if (flag_offload_memory != OFFLOAD_MEMORY_UNIFIED + && flag_offload_memory != OFFLOAD_MEMORY_NONE) + error_at (cloc, + "%<unified_shared_memory%> is incompatible with the " + "selected %<-foffload-memory%> option"); + } else if (!strcmp (p, "dynamic_allocators")) this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS; else if (!strcmp (p, "reverse_offload")) diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 779625144db..5ad41034496 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -47290,8 +47290,14 @@ cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok, enum pragma_context context, bool *if_p) { if (flag_openmp) - omp_requires_mask - = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED); + { + omp_requires_mask + = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED); + if (flag_offload_memory == OFFLOAD_MEMORY_UNIFIED) + omp_requires_mask + = (enum omp_requires) (omp_requires_mask + | OMP_REQUIRES_UNIFIED_SHARED_MEMORY); + } if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)) { @@ -49866,7 +49872,15 @@ cp_parser_omp_requires (cp_parser *parser, cp_token *pragma_tok) if (!strcmp (p, "unified_address")) this_req = OMP_REQUIRES_UNIFIED_ADDRESS; else if (!strcmp (p, "unified_shared_memory")) - this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY; + { + this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY; + + if (flag_offload_memory != OFFLOAD_MEMORY_UNIFIED + && flag_offload_memory != OFFLOAD_MEMORY_NONE) + error_at (cloc, + "%<unified_shared_memory%> is incompatible with the " + "selected %<-foffload-memory%> option"); + } else if (!strcmp (p, "dynamic_allocators")) this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS; else if (!strcmp (p, "reverse_offload")) diff --git a/gcc/fortran/openmp.cc b/gcc/fortran/openmp.cc index 548b36a4b62..bf246f5bf95 100644 --- a/gcc/fortran/openmp.cc +++ b/gcc/fortran/openmp.cc @@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see #include "target-memory.h" /* For gfc_encode_character. */ #include "bitmap.h" #include "omp-api.h" /* For omp_runtime_api_procname. */ +#include "options.h" static gfc_statement omp_code_to_statement (gfc_code *); @@ -6443,6 +6444,11 @@ gfc_match_omp_requires (void) requires_clause = OMP_REQ_UNIFIED_SHARED_MEMORY; if (requires_clauses & OMP_REQ_UNIFIED_SHARED_MEMORY) goto duplicate_clause; + + if (flag_offload_memory != OFFLOAD_MEMORY_UNIFIED + && flag_offload_memory != OFFLOAD_MEMORY_NONE) + gfc_error_now ("unified_shared_memory at %C is incompatible with " + "the selected -foffload-memory option"); } else if (gfc_match (clauses[3]) == MATCH_YES) { diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc index 79c810c86ba..221613ad64b 100644 --- a/gcc/fortran/parse.cc +++ b/gcc/fortran/parse.cc @@ -7358,7 +7358,8 @@ done: if (omp_requires & OMP_REQ_UNIFIED_ADDRESS) omp_requires_mask = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_UNIFIED_ADDRESS); - if (omp_requires & OMP_REQ_UNIFIED_SHARED_MEMORY) + if (omp_requires & OMP_REQ_UNIFIED_SHARED_MEMORY + || flag_offload_memory == OFFLOAD_MEMORY_UNIFIED) omp_requires_mask = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_UNIFIED_SHARED_MEMORY); diff --git a/gcc/testsuite/c-c++-common/gomp/usm-1.c b/gcc/testsuite/c-c++-common/gomp/usm-1.c new file mode 100644 index 00000000000..8d2ba62aba3 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/usm-1.c @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-foffload-memory=pinned" } */ + +#pragma omp requires unified_shared_memory /* { dg-error ".unified_shared_memory. is incompatible with the selected .-foffload-memory. option" } */ diff --git a/gcc/testsuite/gfortran.dg/gomp/usm-1.f90 b/gcc/testsuite/gfortran.dg/gomp/usm-1.f90 new file mode 100644 index 00000000000..340f6bb50a5 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/usm-1.f90 @@ -0,0 +1,6 @@ +! { dg-do compile } +! { dg-additional-options "-foffload-memory=pinned" } + +!$omp requires unified_shared_memory ! { dg-error "unified_shared_memory at .* is incompatible with the selected -foffload-memory option" } + +end diff --git a/libgomp/testsuite/libgomp.fortran/usm-1.f90 b/libgomp/testsuite/libgomp.fortran/usm-1.f90 new file mode 100644 index 00000000000..7147e9925a2 --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/usm-1.f90 @@ -0,0 +1,28 @@ +! { dg-do run } +! { dg-require-effective-target omp_usm } + +! Ensure that USM works for implicit mappings. +! This needs to cover both the initial mapping scan and the rescan that +! happens when some of the mappings aren't no-ops (in this cases there are +! some hidden pointers). + +program usm + use iso_fortran_env + use omp_lib + implicit none + + !$omp requires unified_shared_memory + + integer, parameter :: N = 1024 + real(real64), allocatable :: x(:), y(:) + integer :: i + + allocate(x(N), y(N)) + !$omp target teams distribute parallel do simd + do i=1,N + y(i) = x(i) + enddo + + deallocate(x,y) + +end program usm -- 2.41.0