diff mbox series

OpenMP: Add -fopenmp-force-usm mode

Message ID f0686e35-00b8-418c-9b32-741c40c3c710@baylibre.com
State New
Headers show
Series OpenMP: Add -fopenmp-force-usm mode | expand

Commit Message

Tobias Burnus May 28, 2024, 7:23 p.m. UTC
-fopenmp-force-usm can be useful for some badly written code. Explicity 
using 'omp requires' makes more sense but still. It might also make 
sense for testing purpose.

Unfortunately, I did not see a simple way of testing it. When trying it 
manually, I looked at the 'a.xamdgcn-amdhsa.c' -save-temps file, where 
gcn_data has the omp_requires_mask as second argument and testing showed 
that an explicit pragma and the -f... argument have the same result.

Alternative would be to move this code later, e.g. to lto-cgraph.cc's 
omp_requires_mask, which might be safer (as it avoids changing as many 
locations). On the other hand, it might require more special cases 
elsewhere.*

Comment, suggestions?

Tobias

*I am especially thinking about a global variable and "#pragma omp 
declare target". At least with 'omp requires self_maps' of OpenMP 6, it 
seems as if 'declare target enter(global_var)' should become 
'link(global_var)' where the global_var pointer is updated to point to 
the host version.

At least I don't see how otherwise the "all corresponding list items 
created by the 'enter' clauses specified by declare target directives in 
the compilation unit share storage with the original list items." could 
be fulfilled.

This will require generating different code for 'self_maps' (and, 
potentially / [RFC] 'unified_shared_memory') than normal code, which 
would be the first compiler code-gen change due to USM (→ 
GOMP_OFFLOAD_CAP_SHARED_MEM) for non-host devices.

Comments

Jakub Jelinek May 29, 2024, 6:26 a.m. UTC | #1
On Tue, May 28, 2024 at 09:23:41PM +0200, Tobias Burnus wrote:
> -fopenmp-force-usm can be useful for some badly written code. Explicity
> using 'omp requires' makes more sense but still. It might also make sense
> for testing purpose.
> 
> Unfortunately, I did not see a simple way of testing it. When trying it
> manually, I looked at the 'a.xamdgcn-amdhsa.c' -save-temps file, where
> gcn_data has the omp_requires_mask as second argument and testing showed
> that an explicit pragma and the -f... argument have the same result.
> 
> Alternative would be to move this code later, e.g. to lto-cgraph.cc's
> omp_requires_mask, which might be safer (as it avoids changing as many
> locations). On the other hand, it might require more special cases
> elsewhere.*
> 
> Comment, suggestions?
> 
> Tobias
> 
> *I am especially thinking about a global variable and "#pragma omp declare
> target". At least with 'omp requires self_maps' of OpenMP 6, it seems as if
> 'declare target enter(global_var)' should become 'link(global_var)' where
> the global_var pointer is updated to point to the host version.

How is that option different from
echo '#pragma omp requires unified_shared_memory' > omp-usm.h
gcc -include omp-usm.h
?
I mean with -include you can add anything you want, not just one particular
directive, and adding a separate option for each is just weird.

	Jakub
Jakub Jelinek May 29, 2024, 6:32 a.m. UTC | #2
On Wed, May 29, 2024 at 08:26:04AM +0200, Jakub Jelinek wrote:
> > *I am especially thinking about a global variable and "#pragma omp declare
> > target". At least with 'omp requires self_maps' of OpenMP 6, it seems as if
> > 'declare target enter(global_var)' should become 'link(global_var)' where
> > the global_var pointer is updated to point to the host version.
> 
> How is that option different from
> echo '#pragma omp requires unified_shared_memory' > omp-usm.h
> gcc -include omp-usm.h
> ?
> I mean with -include you can add anything you want, not just one particular
> directive, and adding a separate option for each is just weird.

I mean, if we want to add something, maybe better would an -include like
option that instead of including a file includes it directly.
gcc --include-inline '#pragma omp requires unified_shared_memory' ...

	Jakub
Tobias Burnus May 29, 2024, 6:41 a.m. UTC | #3
Jakub Jelinek wrote:
> How is that option different from
> echo '#pragma omp requires unified_shared_memory' > omp-usm.h
> gcc -include omp-usm.h
> ?
> I mean with -include you can add anything you want, not just one particular
> directive, and adding a separate option for each is just weird.

For C/C++, -include seems to be indeed sufficient (albeit not widely 
known). For Fortran, there at two issues: One placement/semantic issue: 
it has to be added per "compilation unit", i.e. to the specification 
part of a module, subprogram or main program. And a practical issue, 
gfortran shows:

error: command-line option '-include !$omp requires' is valid for 
C/C++/ObjC/ObjC++ but not for Fortran

Thus, for Fortran it is still intrinsically useful – even if one can 
argue whether that feature is needed at all / whether it should be added 
as command-line argument.

Tobias
Tobias Burnus May 29, 2024, 6:49 a.m. UTC | #4
Jakub Jelinek wrote:
> I mean, if we want to add something, maybe better would an -include like
> option that instead of including a file includes it directly.
> gcc --include-inline '#pragma omp requires unified_shared_memory' ...

Likewise for Fortran, but there the question is whether it should be in 
the use-stmt, import-stmt, implicit-part or declaration-part; I guess 
having one --include-inline-use-stmt and --include-inline-declaration 
would make sense …

And, I guess, multiple flags should be permitted, which can then be 
processed as separate lines.

Tobias
Jakub Jelinek May 29, 2024, 6:50 a.m. UTC | #5
On Wed, May 29, 2024 at 08:41:04AM +0200, Tobias Burnus wrote:
> Jakub Jelinek wrote:
> > How is that option different from
> > echo '#pragma omp requires unified_shared_memory' > omp-usm.h
> > gcc -include omp-usm.h
> > ?
> > I mean with -include you can add anything you want, not just one particular
> > directive, and adding a separate option for each is just weird.
> 
> For C/C++, -include seems to be indeed sufficient (albeit not widely known).
> For Fortran, there at two issues: One placement/semantic issue: it has to be
> added per "compilation unit", i.e. to the specification part of a module,
> subprogram or main program. And a practical issue, gfortran shows:
> 
> error: command-line option '-include !$omp requires' is valid for
> C/C++/ObjC/ObjC++ but not for Fortran
> 
> Thus, for Fortran it is still intrinsically useful – even if one can argue
> whether that feature is needed at all / whether it should be added as
> command-line argument.

But then shouldn't we have an option that adds something at the start of
the declaration part of each <whatever is needed>?
I mean, option to add 'implicit none' everywhere, or this
'!$omp requires unified_shared_memory' etc.?

I could live with an one off option for clang compatibility, I just fear
that in 2 years we'll need another one etc. and that solving it in some more
versatile way would be better.

	Jakub
Jakub Jelinek May 29, 2024, 6:52 a.m. UTC | #6
On Wed, May 29, 2024 at 08:49:01AM +0200, Tobias Burnus wrote:
> Jakub Jelinek wrote:
> > I mean, if we want to add something, maybe better would an -include like
> > option that instead of including a file includes it directly.
> > gcc --include-inline '#pragma omp requires unified_shared_memory' ...
> 
> Likewise for Fortran, but there the question is whether it should be in the
> use-stmt, import-stmt, implicit-part or declaration-part; I guess having one
> --include-inline-use-stmt and --include-inline-declaration would make sense

Maybe name it slightly differently for Fortran and have the where it should
be added as one argument, so --whatever=where=what

> And, I guess, multiple flags should be permitted, which can then be
> processed as separate lines.

Obviously.  That was the intent with --include-inline= for C as well,
after all, -include works that way too.
-include a.h -include b.h -include c.h

	Jakub
diff mbox series

Patch

OpenMP: Add -fopenmp-force-usm mode

Add an implicit 'omp requires unified_shared_memory' to all files that
use target constructs ("OMP_REQUIRES_TARGET_USED").  As constructed, the
diagnostic "'unified_shared_memory' clause used lexically after first target
construct or offloading API" is not inhibited.

The option has no effect without -fopenmp and does not affect OpenACC code,
matching what the directive would do.  The name of the command-line option
matches Clang's, added in LLVM 18.

gcc/c-family/ChangeLog:

	* c.opt (fopenmp-force-usm): New.
	* c.opt.urls: Regenerated

gcc/c/ChangeLog:

	* c-parser.cc (c_parser_omp_target_data, c_parser_omp_target_update,
	c_parser_omp_target_enter_data, c_parser_omp_target_exit_data,
	c_parser_omp_target): When setting OMP_REQUIRES_TARGET_USED, also
	set OMP_REQUIRES_UNIFIED_SHARED_MEMORY if -fopenmp-force-usm is
	in force.

gcc/cp/ChangeLog:

	* parser.cc (cp_parser_omp_target_data,
	cp_parser_omp_target_enter_data, cp_parser_omp_target_exit_data,
	cp_parser_omp_target_update, cp_parser_omp_target): When setting
	OMP_REQUIRES_TARGET_USED, also set OMP_REQUIRES_UNIFIED_SHARED_MEMORY
	if -fopenmp-force-usm is in force.


gcc/ChangeLog:

	* doc/invoke.texi (-fopenmp-force-usm): Document new option.

gcc/fortran/ChangeLog:

	* invoke.texi (-fopenmp-force-usm): Document new option.
	* lang.opt (fopenmp-force-usm): New.
	* lang.opt.urls: Regenerate.
	* parse.cc (gfc_parse_file): When setting
	OMP_REQUIRES_TARGET_USED, also set OMP_REQUIRES_UNIFIED_SHARED_MEMORY
	if -fopenmp-force-usm is in force.

 gcc/c-family/c.opt        |  4 ++++
 gcc/c-family/c.opt.urls   |  3 +++
 gcc/c/c-parser.cc         | 50 +++++++++++++++++++++++++++++++++++++----------
 gcc/cp/parser.cc          | 50 +++++++++++++++++++++++++++++++++++++----------
 gcc/doc/invoke.texi       | 11 +++++++++--
 gcc/fortran/invoke.texi   |  7 +++++++
 gcc/fortran/lang.opt      |  4 ++++
 gcc/fortran/lang.opt.urls |  3 +++
 gcc/fortran/parse.cc      | 10 ++++++++--
 9 files changed, 118 insertions(+), 24 deletions(-)

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index fb34c3b7031..4985cd61c48 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -2136,6 +2136,10 @@  fopenmp
 C ObjC C++ ObjC++ LTO Var(flag_openmp)
 Enable OpenMP (implies -frecursive in Fortran).
 
+fopenmp-force-usm
+C ObjC C++ ObjC++ Var(flag_openmp_force_usm)
+Behave as if the source file contained OpenMP's 'requires unified_shared_memory'.
+
 fopenmp-simd
 C ObjC C++ ObjC++ Var(flag_openmp_simd)
 Enable OpenMP's SIMD directives.
diff --git a/gcc/c-family/c.opt.urls b/gcc/c-family/c.opt.urls
index dd455d7c0dc..34b3a395e84 100644
--- a/gcc/c-family/c.opt.urls
+++ b/gcc/c-family/c.opt.urls
@@ -1222,6 +1222,9 @@  UrlSuffix(gcc/C-Dialect-Options.html#index-fopenacc-dim)
 fopenmp
 UrlSuffix(gcc/C-Dialect-Options.html#index-fopenmp) LangUrlSuffix_Fortran(gfortran/Fortran-Dialect-Options.html#index-fopenmp)
 
+fopenmp-force-usm
+UrlSuffix(gcc/C-Dialect-Options.html#index-fopenmp-force-usm) LangUrlSuffix_Fortran(gfortran/Fortran-Dialect-Options.html#index-fopenmp-force-usm)
+
 fopenmp-simd
 UrlSuffix(gcc/C-Dialect-Options.html#index-fopenmp-simd) LangUrlSuffix_Fortran(gfortran/Fortran-Dialect-Options.html#index-fopenmp-simd)
 
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 00f8bf4376e..93c9cd1c9d0 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -23849,8 +23849,14 @@  static tree
 c_parser_omp_target_data (location_t loc, c_parser *parser, 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_openmp_force_usm)
+	omp_requires_mask
+	  = (enum omp_requires) (omp_requires_mask
+				 | OMP_REQUIRES_UNIFIED_SHARED_MEMORY);
+    }
 
   tree clauses
     = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
@@ -23956,8 +23962,14 @@  c_parser_omp_target_update (location_t loc, c_parser *parser,
     }
 
   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_openmp_force_usm)
+	omp_requires_mask
+	  = (enum omp_requires) (omp_requires_mask
+				 | OMP_REQUIRES_UNIFIED_SHARED_MEMORY);
+    }
 
   tree stmt = make_node (OMP_TARGET_UPDATE);
   TREE_TYPE (stmt) = void_type_node;
@@ -24007,8 +24019,14 @@  c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
     }
 
   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_openmp_force_usm)
+	omp_requires_mask
+	  = (enum omp_requires) (omp_requires_mask
+				 | OMP_REQUIRES_UNIFIED_SHARED_MEMORY);
+    }
 
   tree clauses
     = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
@@ -24117,8 +24135,14 @@  c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
     }
 
   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_openmp_force_usm)
+	omp_requires_mask
+	  = (enum omp_requires) (omp_requires_mask
+				 | OMP_REQUIRES_UNIFIED_SHARED_MEMORY);
+    }
 
   tree clauses
     = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
@@ -24223,8 +24247,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_openmp_force_usm)
+	omp_requires_mask
+	  = (enum omp_requires) (omp_requires_mask
+				 | OMP_REQUIRES_UNIFIED_SHARED_MEMORY);
+    }
 
   if (c_parser_next_token_is (parser, CPP_NAME))
     {
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 779625144db..fc2026f0a01 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -46914,8 +46914,14 @@  static tree
 cp_parser_omp_target_data (cp_parser *parser, cp_token *pragma_tok, 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_openmp_force_usm)
+	omp_requires_mask
+	  = (enum omp_requires) (omp_requires_mask
+				 | OMP_REQUIRES_UNIFIED_SHARED_MEMORY);
+    }
 
   tree clauses
     = cp_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
@@ -47029,8 +47035,14 @@  cp_parser_omp_target_enter_data (cp_parser *parser, cp_token *pragma_tok,
     }
 
   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_openmp_force_usm)
+	omp_requires_mask
+	  = (enum omp_requires) (omp_requires_mask
+				 | OMP_REQUIRES_UNIFIED_SHARED_MEMORY);
+    }
 
   tree clauses
     = cp_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
@@ -47144,8 +47156,14 @@  cp_parser_omp_target_exit_data (cp_parser *parser, cp_token *pragma_tok,
     }
 
   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_openmp_force_usm)
+	omp_requires_mask
+	  = (enum omp_requires) (omp_requires_mask
+				 | OMP_REQUIRES_UNIFIED_SHARED_MEMORY);
+    }
 
   tree clauses
     = cp_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
@@ -47255,8 +47273,14 @@  cp_parser_omp_target_update (cp_parser *parser, cp_token *pragma_tok,
     }
 
   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_openmp_force_usm)
+	omp_requires_mask
+	  = (enum omp_requires) (omp_requires_mask
+				 | OMP_REQUIRES_UNIFIED_SHARED_MEMORY);
+    }
 
   tree stmt = make_node (OMP_TARGET_UPDATE);
   TREE_TYPE (stmt) = void_type_node;
@@ -47290,8 +47314,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_openmp_force_usm)
+	omp_requires_mask
+	  = (enum omp_requires) (omp_requires_mask
+				 | OMP_REQUIRES_UNIFIED_SHARED_MEMORY);
+    }
 
   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
     {
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 2cba380718b..d6a19c8f561 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -203,8 +203,8 @@  in the following sections.
 -ffreestanding  -fgimple  -fgnu-tm  -fgnu89-inline  -fhosted
 -flax-vector-conversions  -fms-extensions
 -foffload=@var{arg}  -foffload-options=@var{arg}
--fopenacc  -fopenacc-dim=@var{geom}
--fopenmp  -fopenmp-simd  -fopenmp-target-simd-clone@r{[}=@var{device-type}@r{]}
+-fopenacc  -fopenacc-dim=@var{geom}  -fopenmp  -fopenmp-force-usm
+-fopenmp-simd  -fopenmp-target-simd-clone@r{[}=@var{device-type}@r{]}
 -fpermitted-flt-eval-methods=@var{standard}
 -fplan9-extensions  -fsigned-bitfields  -funsigned-bitfields
 -fsigned-char  -funsigned-char  -fstrict-flex-arrays[=@var{n}]
@@ -2817,6 +2817,13 @@  implies @option{-pthread}, and thus is only supported on targets that
 have support for @option{-pthread}. @option{-fopenmp} implies
 @option{-fopenmp-simd}.
 
+@opindex fopenmp-force-usm
+@cindex OpenMP Unified Shared Memory
+@item -fopenmp-force-usm
+Behave as if each source file contained the OpenMP directive @code{requires}
+with the @code{unified_shared_memory} clause.  This option only has an effect
+if @option{-fopenmp} has been specified.
+
 @opindex fopenmp-simd
 @cindex OpenMP SIMD
 @cindex SIMD
diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi
index 6bc42afe2c4..a825941e1ae 100644
--- a/gcc/fortran/invoke.texi
+++ b/gcc/fortran/invoke.texi
@@ -445,6 +445,13 @@  implies @option{-pthread}, and thus is only supported on targets that
 have support for @option{-pthread}. @option{-fopenmp} implies
 @option{-fopenmp-simd} and @option{-frecursive}.
 
+@opindex fopenmp-force-usm
+@cindex OpenMP Unified Shared Memory
+@item -fopenmp-force-usm
+Behave as if each source file contained the OpenMP directive @code{requires}
+with the @code{unified_shared_memory} clause.  This option only has an effect
+if @option{-fopenmp} has been specified.
+
 @opindex fopenmp-allocators
 @cindex OpenMP Allocators
 @item -fopenmp-allocators
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
index 5efd4a0129a..bf72b0e4ff3 100644
--- a/gcc/fortran/lang.opt
+++ b/gcc/fortran/lang.opt
@@ -712,6 +712,10 @@  fopenmp
 Fortran LTO
 ; Documented in C
 
+fopenmp-force-usm
+Fortran
+; Documented in C
+
 fopenmp-simd
 Fortran
 ; Documented in C
diff --git a/gcc/fortran/lang.opt.urls b/gcc/fortran/lang.opt.urls
index e335b42e357..d4e4efcb437 100644
--- a/gcc/fortran/lang.opt.urls
+++ b/gcc/fortran/lang.opt.urls
@@ -118,6 +118,9 @@  UrlSuffix(gcc/C-Dialect-Options.html#index-fopenacc-dim)
 fopenmp
 UrlSuffix(gcc/C-Dialect-Options.html#index-fopenmp) LangUrlSuffix_Fortran(gfortran/Fortran-Dialect-Options.html#index-fopenmp)
 
+fopenmp-force-usm
+UrlSuffix(gcc/C-Dialect-Options.html#index-fopenmp-force-usm) LangUrlSuffix_Fortran(gfortran/Fortran-Dialect-Options.html#index-fopenmp-force-usm)
+
 fopenmp-simd
 UrlSuffix(gcc/C-Dialect-Options.html#index-fopenmp-simd) LangUrlSuffix_Fortran(gfortran/Fortran-Dialect-Options.html#index-fopenmp-simd)
 
diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc
index 79c810c86ba..78abafe1f53 100644
--- a/gcc/fortran/parse.cc
+++ b/gcc/fortran/parse.cc
@@ -7350,8 +7350,14 @@  done:
     }
 
   if (omp_target_seen)
-    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_openmp_force_usm)
+	omp_requires_mask
+	  = (enum omp_requires) (omp_requires_mask
+				 | OMP_REQUIRES_UNIFIED_SHARED_MEMORY);
+    }
   if (omp_requires & OMP_REQ_REVERSE_OFFLOAD)
     omp_requires_mask = (enum omp_requires) (omp_requires_mask
 					     | OMP_REQUIRES_REVERSE_OFFLOAD);