diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -116,10 +116,29 @@ OMP_PROC_BIND_unknown ]; } + +// static and auto are C++ keywords so need a capital to disambiguate +def OMP_SCHEDULE_Static : ClauseVal<"Static", 2, 1> {} +def OMP_SCHEDULE_Dynamic : ClauseVal<"Dynamic", 3, 1> {} +def OMP_SCHEDULE_Guided : ClauseVal<"Guided", 4, 1> {} +def OMP_SCHEDULE_Auto : ClauseVal<"Auto", 5, 1> {} +def OMP_SCHEDULE_Runtime : ClauseVal<"Runtime", 6, 1> {} +def OMP_SCHEDULE_Default : ClauseVal<"Default", 7, 0> { let isDefault = 1; } + def OMPC_Schedule : Clause<"schedule"> { let clangClass = "OMPScheduleClause"; let flangClass = "OmpScheduleClause"; + let enumClauseValue = "ScheduleKind"; + let allowedClauseValues = [ + OMP_SCHEDULE_Static, + OMP_SCHEDULE_Dynamic, + OMP_SCHEDULE_Guided, + OMP_SCHEDULE_Auto, + OMP_SCHEDULE_Runtime, + OMP_SCHEDULE_Default + ]; } + def OMPC_Ordered : Clause<"ordered"> { let clangClass = "OMPOrderedClause"; let flangClassValue = "ScalarIntConstantExpr"; @@ -238,8 +257,14 @@ def OMPC_NonTemporal : Clause<"nontemporal"> { let clangClass = "OMPNontemporalClause"; } + +def OMP_ORDER_concurrent : ClauseVal<"default",2,0> { let isDefault = 1; } def OMPC_Order : Clause<"order"> { let clangClass = "OMPOrderClause"; + let enumClauseValue = "OrderKind"; + let allowedClauseValues = [ + OMP_ORDER_concurrent + ]; } def OMPC_Destroy : Clause<"destroy"> { let clangClass = "OMPDestroyClause"; 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 @@ -96,6 +96,59 @@ let assemblyFormat = "attr-dict"; } +//===----------------------------------------------------------------------===// +// 2.9.2 do Construct +//===----------------------------------------------------------------------===// + +def DoOp : OpenMP_Op<"do", [AttrSizedOperandSegments]> { + let summary = "workshare loop construct"; + let description = [{ + The workshare loop construct specifies that the iterations of the associated + loops will be executed in parallel by threads in the current context. These + iterations are spread across threads that already exist in the enclosing + parallel region + + The $private_vars, $firstprivate_vars, $lastprivate_vars and $linear_vars + parameters are a variadic list of variables that specify the data sharing + attribute of those variables. The $linear_step_vars variable additionally + specifies the step for each associated linear variable. Note that the + $linear_vars and $linear_step_vars variadic lists should contain the same + number of elements. + + The optional $schedule_val attribute specifies the loop schedule for this + loop, determining how the loop is distributed across the parallel threads. + The optional $schedule_chunk_var associated with this determines further + controls this distribution. + + The optional $collapse_val attribute specifies that the following number of + loops should be collapsed into a single loop before being distributed. + + The $nowait attribute, when present, signifies that there should be no + implicit barrier at the end of the loop. + + The optional $ordered_val attribute specifies how many loops are associated + with the do loop construct. + + The optional order attribute specifies which order the iterations of the + associate loops are executed in. Currently the only option for this + attribute is "concurrent". + }]; + + let arguments = (ins Variadic:$private_vars, + Variadic:$firstprivate_vars, + Variadic:$lastprivate_vars, + Variadic:$linear_vars, + Variadic:$linear_step_vars, + OptionalAttr:$schedule_val, + Optional:$schedule_chunk_var, + OptionalAttr:$collapse_val, + OptionalAttr:$nowait, + OptionalAttr:$ordered_val, + OptionalAttr:$order_val); + + let regions = (region AnyRegion:$region); +} + //===----------------------------------------------------------------------===// // 2.10.4 taskyield Construct //===----------------------------------------------------------------------===// diff --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir --- a/mlir/test/Dialect/OpenMP/ops.mlir +++ b/mlir/test/Dialect/OpenMP/ops.mlir @@ -113,3 +113,33 @@ return } + +func @omp_do(%data_var : memref, %linear_var : si32, %chunk_var : si32) -> () { + + // CHECK: "omp.do"(%{{.*}}) + "omp.do" (%data_var) ({ + omp.terminator + }) {operand_segment_sizes = dense<[1,0,0,0,0,0]> : vector<6xi32>, collapse_val = 2, ordered_val = 1} : + (memref) -> () + + // CHECK: "omp.do"(%{{.*}}, %{{.*}}) + "omp.do" (%data_var, %linear_var) ({ + omp.terminator + }) {operand_segment_sizes = dense<[0,0,0,1,1,0]> : vector<6xi32>, schedule_val = "Static"} : + (memref, si32) -> () + + // CHECK: "omp.do"(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) + "omp.do" (%data_var, %data_var, %data_var, %data_var, %linear_var, %chunk_var) ({ + omp.terminator + }) {operand_segment_sizes = dense<[1,1,1,1,1,1]> : vector<6xi32>, schedule_val = "Dynamic", collapse_val = 3, ordered_val = 2} : + (memref, memref, memref, memref, si32, si32) -> () + + // CHECK: "omp.do"(%{{.*}}) + "omp.do" (%data_var) ({ + omp.terminator + }) {operand_segment_sizes = dense<[1,0,0,0,0,0]> : vector<6xi32>, nowait, schedule_val = "Auto"} : + (memref) -> () + + + return +}