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);