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(-)
@@ -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.
@@ -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)
@@ -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))
{
@@ -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))
{
@@ -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
@@ -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
@@ -712,6 +712,10 @@ fopenmp
Fortran LTO
; Documented in C
+fopenmp-force-usm
+Fortran
+; Documented in C
+
fopenmp-simd
Fortran
; Documented in C
@@ -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)
@@ -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);