diff --git a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp index d54562f5c5e967..d78f898d499e4f 100644 --- a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp +++ b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp @@ -194,6 +194,10 @@ void OpenMPCounterVisitor::Post(const OmpDefaultClause::Type &c) { clauseDetails += "type=" + std::string{OmpDefaultClause::EnumToString(c)} + ";"; } +void OpenMPCounterVisitor::Post(const OmpDeviceTypeClause::Type &c) { + clauseDetails += + "type=" + std::string{OmpDeviceTypeClause::EnumToString(c)} + ";"; +} void OpenMPCounterVisitor::Post( const OmpDefaultmapClause::ImplicitBehavior &c) { clauseDetails += diff --git a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.h b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.h index 188a7e9b877646..e1882f7b436352 100644 --- a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.h +++ b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.h @@ -70,6 +70,7 @@ struct OpenMPCounterVisitor { void Post(const OmpDefaultClause::Type &c); void Post(const OmpDefaultmapClause::ImplicitBehavior &c); void Post(const OmpDefaultmapClause::VariableCategory &c); + void Post(const OmpDeviceTypeClause::Type &c); void Post(const OmpScheduleModifierType::ModType &c); void Post(const OmpLinearModifier::Type &c); void Post(const OmpDependenceType::Type &c); diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index f0716c7da7f799..46e426942ca793 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -528,6 +528,8 @@ class ParseTreeDumper { NODE_ENUM(OmpScheduleClause, ScheduleType) NODE(parser, OmpDeviceClause) NODE_ENUM(OmpDeviceClause, DeviceModifier) + NODE(parser, OmpDeviceTypeClause) + NODE_ENUM(OmpDeviceTypeClause, Type) NODE(parser, OmpScheduleModifier) NODE(OmpScheduleModifier, Modifier1) NODE(OmpScheduleModifier, Modifier2) diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 9792e995fc39aa..c439e3c7d9f69c 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -3396,6 +3396,12 @@ struct OmpDeviceClause { std::tuple, ScalarIntExpr> t; }; +// device_type(any | host | nohost) +struct OmpDeviceTypeClause { + ENUM_CLASS(Type, Any, Host, Nohost) + WRAPPER_CLASS_BOILERPLATE(OmpDeviceTypeClause, Type); +}; + // 2.12 if-clause -> IF ([ directive-name-modifier :] scalar-logical-expr) struct OmpIfClause { TUPLE_CLASS_BOILERPLATE(OmpIfClause); diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index cbcc6bfef65156..a89e9f0d196453 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -105,6 +105,12 @@ TYPE_PARSER(construct( ":"), scalarIntExpr)) +// device_type(any | host | nohost) +TYPE_PARSER(construct( + "ANY" >> pure(OmpDeviceTypeClause::Type::Any) || + "HOST" >> pure(OmpDeviceTypeClause::Type::Host) || + "NOHOST" >> pure(OmpDeviceTypeClause::Type::Nohost))) + // 2.12 IF (directive-name-modifier: scalar-logical-expr) TYPE_PARSER(construct( maybe( @@ -208,6 +214,8 @@ TYPE_PARSER( parenthesized(Parser{}))) || "DEVICE" >> construct(construct( parenthesized(Parser{}))) || + "DEVICE_TYPE" >> construct(construct( + parenthesized(Parser{}))) || "DIST_SCHEDULE" >> construct(construct( parenthesized("STATIC" >> maybe("," >> scalarIntExpr)))) || diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index e0f763ca03a885..581496610c3dd0 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2616,6 +2616,7 @@ class UnparseVisitor { WALK_NESTED_ENUM(OmpMapType, Type) // OMP map-type WALK_NESTED_ENUM(OmpScheduleClause, ScheduleType) // OMP schedule-type WALK_NESTED_ENUM(OmpDeviceClause, DeviceModifier) // OMP device modifier + WALK_NESTED_ENUM(OmpDeviceTypeClause, Type) // OMP DEVICE_TYPE WALK_NESTED_ENUM(OmpIfClause, DirectiveNameModifier) // OMP directive-modifier WALK_NESTED_ENUM(OmpCancelType, Type) // OMP cancel-type #undef WALK_NESTED_ENUM diff --git a/flang/test/Parser/omp-declare_target-device_type.f90 b/flang/test/Parser/omp-declare_target-device_type.f90 new file mode 100644 index 00000000000000..2f6b68ab30f6e9 --- /dev/null +++ b/flang/test/Parser/omp-declare_target-device_type.f90 @@ -0,0 +1,22 @@ +! RUN: %flang_fc1 -fdebug-unparse -fopenmp %s | FileCheck --ignore-case %s +! RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp %s | FileCheck --check-prefix="PARSE-TREE" %s + +subroutine openmp_declare_target + !CHECK: !$omp declare target device_type(host) + !$omp declare target device_type(host) + !CHECK: !$omp declare target device_type(nohost) + !$omp declare target device_type(nohost) + !CHECK: !$omp declare target device_type(any) + !$omp declare target device_type(any) + integer :: a(1024), i + !CHECK: do + do i = 1, 1024 + a(i) = i + !CHECK: end do + end do + +!PARSE-TREE: OpenMPDeclarativeConstruct -> OpenMPDeclareTargetConstruct +!PARSE-TREE: OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> Type = Host +!PARSE-TREE: OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> Type = Nohost +!PARSE-TREE: OmpDeclareTargetSpecifier -> OmpDeclareTargetWithClause -> OmpClauseList -> OmpClause -> DeviceType -> OmpDeviceTypeClause -> Type = Any +END subroutine openmp_declare_target diff --git a/flang/test/Semantics/OpenMP/omp-declare-target01.f90 b/flang/test/Semantics/OpenMP/omp-declare-target01.f90 index 3cb7cfb14c3732..862b4c5866f3fb 100644 --- a/flang/test/Semantics/OpenMP/omp-declare-target01.f90 +++ b/flang/test/Semantics/OpenMP/omp-declare-target01.f90 @@ -51,6 +51,8 @@ module declare_target01 !$omp declare target to (my_var) + !$omp declare target to (my_var) device_type(host) + !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive !$omp declare target to (my_var%t_i) @@ -65,6 +67,8 @@ module declare_target01 !$omp declare target to (arr) + !$omp declare target to (arr) device_type(nohost) + !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive !$omp declare target to (arr(1)) @@ -82,6 +86,8 @@ module declare_target01 !$omp declare target link (my_var2) + !$omp declare target link (my_var2) device_type(any) + !ERROR: A variable that is part of another variable (as an array or structure element) cannot appear on the DECLARE TARGET directive !$omp declare target link (my_var2%t_i) diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td index 9f732e8c613417..a01d38327b7c7c 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -222,6 +222,9 @@ def OMPC_Device : Clause<"device"> { let clangClass = "OMPDeviceClause"; let flangClass = "OmpDeviceClause"; } +def OMPC_DeviceType : Clause<"device_type"> { + let flangClass = "OmpDeviceTypeClause"; +} def OMPC_Threads : Clause<"threads"> { let clangClass = "OMPThreadsClause"; } def OMPC_Simd : Clause<"simd"> { let clangClass = "OMPSIMDClause"; } def OMPC_Map : Clause<"map"> { @@ -397,7 +400,6 @@ def OMPC_Uniform : Clause<"uniform"> { let flangClass = "Name"; let isValueList = true; } -def OMPC_DeviceType : Clause<"device_type"> {} def OMPC_Match : Clause<"match"> {} def OMPC_AdjustArgs : Clause<"adjust_args"> { } def OMPC_AppendArgs : Clause<"append_args"> { } @@ -1095,6 +1097,9 @@ def OMP_DeclareTarget : Directive<"declare target"> { VersionedClause, VersionedClause ]; + let allowedOnceClauses = [ + VersionedClause + ]; } def OMP_EndDeclareTarget : Directive<"end declare target"> {} def OMP_DistributeParallelFor : Directive<"distribute parallel for"> {