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

Reply via email to