diff --git a/clang/lib/Testing/CMakeLists.txt b/clang/lib/Testing/CMakeLists.txt --- a/clang/lib/Testing/CMakeLists.txt +++ b/clang/lib/Testing/CMakeLists.txt @@ -26,4 +26,6 @@ target_link_libraries(clangTesting PRIVATE llvm_gtest + clangBasic + clangFrontend ) 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 @@ -394,7 +394,7 @@ 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; @@ -463,6 +463,71 @@ let assemblyFormat = [{ ( `(` $results^ `:` type($results) `)` )? attr-dict}]; } +//===----------------------------------------------------------------------===// +// 2.9.4.1 distribute Construct +//===----------------------------------------------------------------------===// + +def DistributeOp : OpenMP_Op<"distribute", [AttrSizedOperandSegments, + AllTypesMatch<["lowerBound", "upperBound", "step"]>]> { + let summary = "distribute loop construct"; + let description = [{ + The distribute construct specifies that the iterations of one or more loop + will be executed by the initial teams in the context of their implicit + tasks. The iterations are distributed across the initial threads of all + initial teams that execute the teams region to which the distribute region + binds. + + The distribute loop construct specifies that the iterations of the loop(s) + will be executed in parallel by threads in the current context. These + iterations are spread across threads that already exist in the enclosing + region. 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. + + // TODO: the following variables will be defined later + `private_var`, `firstprivate_var`, and `lastprivate_var` arguments are + variadic list of operands that specify the data sharing attributes of the + list of values + + The optional `dist_schedule_var` attribute specifies the schedule for this + loop, determining how the loop is distributed across the parallel threads. + The optional `schedule_chunk` associated with this determines further + controls this distribution. + + The optional `collapse` attribute specifies the number of loops which + are collapsed to form the distribute loop. + }]; + + let arguments = (ins Variadic:$lowerBound, + Variadic:$upperBound, + Variadic:$step, + OptionalAttr:$dist_schedule_var, + Optional:$schedule_chunk, + Confined, [IntMinValue<1>]>:$collapse_val, + Variadic:$allocate_vars, + Variadic:$allocators_vars, + UnitAttr:$inclusive); + + + let assemblyFormat = [{ + oilist(`schedule` `(` + custom( + $dist_schedule_var, + $schedule_chunk, type($schedule_chunk)) `)` + |`collapse` `(` $collapse_val `)` + | `allocate` `(` + custom( + $allocate_vars, type($allocate_vars), + $allocators_vars, type($allocators_vars) + ) `)` + + ) `for` custom($region, $lowerBound, $upperBound, $step, + type($step), $inclusive) attr-dict + }]; + + let regions = (region AnyRegion:$region); +} + //===----------------------------------------------------------------------===// // 2.10.1 task Construct //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp --- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp +++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp @@ -207,6 +207,58 @@ return success(); } +//===---------------------------------------------------------------------===// +// Parser for Distribute Schedule Clause +//===---------------------------------------------------------------------===// + +static ParseResult +parseDistributeScheduleClause( + OpAsmParser &parser, ClauseScheduleKindAttr &scheduleAttr, + Optional &chunkSize, Type &chunkType) { + + StringRef keyword; + if (parser.parseKeyword(&keyword)) + return failure(); + llvm::Optional schedule = + symbolizeClauseScheduleKind(keyword); + if (!schedule) + return parser.emitError(parser.getNameLoc()) << + " expected scheudle kind"; + + scheduleAttr = ClauseScheduleKindAttr::get(parser.getContext(), *schedule); + + switch (*schedule) { + case ClauseScheduleKind::Static: + case ClauseScheduleKind::Dynamic: + case ClauseScheduleKind::Guided: + if (succeeded(parser.parseOptionalEqual())) { + chunkSize = OpAsmParser::UnresolvedOperand{}; + if (parser.parseOperand(*chunkSize) || + parser.parseColonType(chunkType)) + return failure(); + } else { + chunkSize = llvm::NoneType::None; + } + break; + case ClauseScheduleKind::Auto: + case ClauseScheduleKind::Runtime: + chunkSize = llvm::NoneType::None; + } + + return success(); +} + +// Print distribute schedule clause +static void printDistributeScheduleClause(OpAsmPrinter &p, Operation *op, + ClauseScheduleKindAttr schedAttr, + Value scheduleChunkVar, + Type scheduleChunkType) { + p << stringifyClauseScheduleKind(schedAttr.getValue()); + if (scheduleChunkVar) + p << " = " << scheduleChunkVar << " : " << scheduleChunkVar.getType(); + +} + /// schedule ::= `schedule` `(` sched-list `)` /// sched-list ::= sched-val | sched-val sched-list | /// sched-val `,` sched-modifier @@ -517,7 +569,7 @@ /// loop-bounds := `(` ssa-id-list `)` to `(` ssa-id-list `)` inclusive? steps /// steps := `step` `(`ssa-id-list`)` ParseResult -parseWsLoopControl(OpAsmParser &parser, Region ®ion, +parseLoopControl(OpAsmParser &parser, Region ®ion, SmallVectorImpl &lowerBound, SmallVectorImpl &upperBound, SmallVectorImpl &steps, @@ -560,7 +612,7 @@ return success(); } -void printWsLoopControl(OpAsmPrinter &p, Operation *op, Region ®ion, +void printLoopControl(OpAsmPrinter &p, Operation *op, Region ®ion, ValueRange lowerBound, ValueRange upperBound, ValueRange steps, TypeRange loopVarTypes, UnitAttr inclusive) {