This patch adds parser suppert for the device_type clause used by the Declare Target directive.
Differential Revision: https://reviews.llvm.org/D143671
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 +=
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);
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)
std::tuple<std::optional<DeviceModifier>, 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);
":"),
scalarIntExpr))
+// device_type(any | host | nohost)
+TYPE_PARSER(construct<OmpDeviceTypeClause>(
+ "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<OmpIfClause>(
maybe(
parenthesized(Parser<OmpDependClause>{}))) ||
"DEVICE" >> construct<OmpClause>(construct<OmpClause::Device>(
parenthesized(Parser<OmpDeviceClause>{}))) ||
+ "DEVICE_TYPE" >> construct<OmpClause>(construct<OmpClause::DeviceType>(
+ parenthesized(Parser<OmpDeviceTypeClause>{}))) ||
"DIST_SCHEDULE" >>
construct<OmpClause>(construct<OmpClause::DistSchedule>(
parenthesized("STATIC" >> maybe("," >> scalarIntExpr)))) ||
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
--- /dev/null
+! 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
!$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)
!$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))
!$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)
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"> {
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"> { }
VersionedClause<OMPC_Link>,
VersionedClause<OMPC_Indirect>
];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_DeviceType, 50>
+ ];
}
def OMP_EndDeclareTarget : Directive<"end declare target"> {}
def OMP_DistributeParallelFor : Directive<"distribute parallel for"> {