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 _ 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"; @@ -235,8 +254,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_var parameter 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_var parameter 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, + Optional:$collapse_var, + OptionalAttr:$nowait, + Optional:$ordered_var, + 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, %collapse_var : si32, %ordered_var : si32) -> () { + + // CHECK: "omp.do"(%{{.*}}, %{{.*}}, %{{.*}}) + "omp.do" (%data_var, %collapse_var, %ordered_var) ({ + omp.terminator + }) {operand_segment_sizes = dense<[1,0,0,0,0,0,1,1]> : vector<8xi32>} : + (memref, si32, si32) -> () + + // CHECK: "omp.do"(%{{.*}}, %{{.*}}) + "omp.do" (%data_var, %linear_var) ({ + omp.terminator + }) {operand_segment_sizes = dense<[0,0,0,1,1,0,0,0]> : vector<8xi32>, schedule_val = "static_"} : + (memref, si32) -> () + + // CHECK: "omp.do"(%{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) + "omp.do" (%data_var, %data_var, %data_var, %data_var, %linear_var, %chunk_var, %collapse_var, %ordered_var) ({ + omp.terminator + }) {operand_segment_sizes = dense<[1,1,1,1,1,1,1,1]> : vector<8xi32>, schedule_val = "dynamic"} : + (memref, memref, memref, memref, si32, si32, si32, si32) -> () + + // CHECK: "omp.do"(%{{.*}}, %{{.*}}, %{{.*}}) + "omp.do" (%data_var, %collapse_var, %ordered_var) ({ + omp.terminator + }) {operand_segment_sizes = dense<[1,0,0,0,0,0,1,1]> : vector<8xi32>, nowait, schedule_val = "auto_"} : + (memref, si32, si32) -> () + + + return +}