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 @@ -403,12 +403,80 @@ custom( $reduction_vars, type($reduction_vars), $reductions ) `)` - ) `for` custom($region, $lowerBound, $upperBound, $step, + ) `for` custom($region, $lowerBound, $upperBound, $step, type($step), $inclusive) attr-dict }]; let hasVerifier = 1; } +//===---------------------------------------------------------------------===// +// OpenMP Canonical Loop Operation +//===---------------------------------------------------------------------===// +def CanonicalLoopOp : OpenMP_Op<"canonical_loop", [AttrSizedOperandSegments, + AllTypesMatch<["lowerBound", "upperBound", "step"]>]> { + let summary = "OpenMP Canonical Loop Operation"; + let description = [{ + This is a work in progress. The aim of the operation is to return + a that confirms the canonical form as describted by the + OpenMP Specification https://www.openmp.org/spec-html/5.0/openmpsu40.html. + The lower and upper bounds specify a half-open range: the range includes + the lower bound but does not include the upper bound. If the `inclusive` + attribute is specified then the upper bound is also included. For the + following FORTRAN code: + ``` + DO u = lb1, ub1 + dosomthing (u) + DO v = lb2, ub2 + dosomthing (v) + END DO + END DO + ``` + + ``` + %outerinfo, %innerinfo = omp.canonical_loop for (%iv1) : + i32 = (%lb1) to (%ub1) step (%step1) { + do_somthing (%iv1) + %inner = omp.canonical_loop for (%iv2) : + i32 = (%lb2) to (%ub2) step (%step2) { + do_somthing (%iv2) + omp.yield + } + } + omp.yield %innerinfo + } + ``` + "(%lb) to (%ub) step (%step)" is Fortran-style and may not exactly + match the naive C/C++ for-stmt. Optional If_expr/conditional check can + be used for the C/C++ style for loop + }]; + let arguments = (ins Variadic:$lowerBound, + Variadic:$upperBound, + Variadic:$step, + Optional:$if_expr, + UnitAttr:$inclusive + ); + + // let results = (outs Variadic:$loopInfo); + // Do we need to define a type for this? + // that will contain all the information + // about the canonical loop + let regions = (region AnyRegion:$region); + + + + let assemblyFormat = [{ + oilist(`if` `(` $if_expr `)`) + `for` custom($region, $lowerBound, $upperBound, $step, + type($step), $inclusive) attr-dict + }]; + // Should we use the same LoopControl or + // define a new one for canonical loop operation + // + + let hasCustomAssemblyFormat = 1; + +} + //===----------------------------------------------------------------------===// // Simd construct [2.9.3.1] //===----------------------------------------------------------------------===//