diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td --- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td +++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td @@ -1629,4 +1629,33 @@ let hasVerifier = 1; } +//===----------------------------------------------------------------------===// +// 8.2 requires directive +//===----------------------------------------------------------------------===// + +def ClauseRequiresNone : I32BitEnumAttrCaseNone<"none">; +def ClauseRequiresReverseOffload : I32BitEnumAttrCaseBit<"reverse_offload", 0>; +def ClauseRequiresUnifiedAddress : I32BitEnumAttrCaseBit<"unified_address", 1>; +def ClauseRequiresUnifiedSharedMemory + : I32BitEnumAttrCaseBit<"unified_shared_memory", 2>; +def ClauseRequiresDynamicAllocators + : I32BitEnumAttrCaseBit<"dynamic_allocators", 3>; + +def ClauseRequires : I32BitEnumAttr< + "ClauseRequires", + "requires clause", + [ + ClauseRequiresNone, + ClauseRequiresReverseOffload, + ClauseRequiresUnifiedAddress, + ClauseRequiresUnifiedSharedMemory, + ClauseRequiresDynamicAllocators + ]> { + let genSpecializedAttr = 0; + let cppNamespace = "::mlir::omp"; +} +def ClauseRequiresAttr : + EnumAttr { +} + #endif // OPENMP_OPS diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td --- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td +++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td @@ -49,7 +49,7 @@ def OffloadModuleInterface : OpInterface<"OffloadModuleInterface"> { let description = [{ - Operations that represent a module for offloading (host or device) + Operations that represent a module for offloading (host or device) should have this interface. }]; @@ -58,23 +58,23 @@ let methods = [ InterfaceMethod< /*description=*/[{ - Set the attribute IsDeviceAttr on the current module with the - specified boolean argument. + Set the attribute IsDeviceAttr on the current module with the + specified boolean argument. }], /*retTy=*/"void", - /*methodName=*/"setIsDevice", + /*methodName=*/"setIsDevice", (ins "bool":$isDevice), [{}], [{ $_op->setAttr( mlir::StringAttr::get($_op->getContext(), llvm::Twine{"omp.is_device"}), mlir::omp::IsDeviceAttr::get($_op->getContext(), isDevice)); }]>, - InterfaceMethod< + InterfaceMethod< /*description=*/[{ Get the IsDeviceAttr attribute on the current module if it exists and return its value, if it doesn't exit it returns false by default. }], /*retTy=*/"bool", - /*methodName=*/"getIsDevice", + /*methodName=*/"getIsDevice", (ins), [{}], [{ if (Attribute isDevice = $_op->getAttr("omp.is_device")) if (isDevice.isa()) @@ -110,6 +110,54 @@ assumeTeamsOversubscription, assumeThreadsOversubscription, assumeNoThreadState, assumeNoNestedParallelism)); }]>, + InterfaceMethod< + /*description=*/[{ + Get the omp.requires attribute on the operator if it's present and + return its value. If it doesn't exist, return `ClauseRequires::none` by + default. + }], + /*retTy=*/"::mlir::omp::ClauseRequires", + /*methodName=*/"getRequires", + (ins), [{}], [{ + if (Attribute requiresAttr = $_op->getAttr("omp.requires")) + if (auto requiresVal = requiresAttr.dyn_cast()) + return requiresVal.getValue(); + return mlir::omp::ClauseRequires::none; + }]>, + InterfaceMethod< + /*description=*/[{ + Set the omp.requires attribute on the operator to the specified clauses. + }], + /*retTy=*/"void", + /*methodName=*/"setRequires", + (ins "::mlir::omp::ClauseRequires":$clauses), [{}], [{ + $_op->setAttr(mlir::StringAttr::get($_op->getContext(), "omp.requires"), + mlir::omp::ClauseRequiresAttr::get($_op->getContext(), clauses)); + }]>, + InterfaceMethod< + /*description=*/[{ + Get the omp.atomic_default_mem_order attribute on the operator and + return its value if it's present. + }], + /*retTy=*/"std::optional<::mlir::omp::ClauseMemoryOrderKind>", + /*methodName=*/"getAtomicDefaultMemOrder", + (ins), [{}], [{ + if (mlir::Attribute atomicDefaultAttr = $_op->getAttr("omp.atomic_default_mem_order")) + if (auto atomicDefault = atomicDefaultAttr.dyn_cast()) + return atomicDefault.getValue(); + return std::nullopt; + }]>, + InterfaceMethod< + /*description=*/[{ + Set the omp.atomic_default_mem_order attribute on the operator to the + specified memory order kind. + }], + /*retTy=*/"void", + /*methodName=*/"setAtomicDefaultMemOrder", + (ins "::mlir::omp::ClauseMemoryOrderKind":$order), [{}], [{ + $_op->setAttr(mlir::StringAttr::get($_op->getContext(), "omp.atomic_default_mem_order"), + mlir::omp::ClauseMemoryOrderKindAttr::get($_op->getContext(), order)); + }]> ]; }