@@ -2383,15 +2383,38 @@ def OpenACC_LoopOp : OpenACC_Op<"loop",
23832383 let summary = "loop construct";
23842384
23852385 let description = [{
2386- The "acc.loop" operation represents the OpenACC loop construct. The lower
2387- and upper bounds specify a half-open range: the range includes the lower
2388- bound but does not include the upper bound. If the `inclusive` attribute is
2389- set then the upper bound is included.
2386+ The `acc.loop` operation represents the OpenACC loop construct and when
2387+ bounds are included, the associated source language loop iterators. The
2388+ lower and upper bounds specify a half-open range: the range includes the
2389+ lower bound but does not include the upper bound. If the `inclusive`
2390+ attribute is set then the upper bound is included.
2391+
2392+ In cases where the OpenACC loop directive needs to capture multiple
2393+ source language loops, such as in the case of `collapse` or `tile`,
2394+ the multiple induction arguments are used to capture each case. Having
2395+ such a representation makes sure no intermediate transformation such
2396+ as Loop Invariant Code Motion breaks the property requested by the
2397+ clause on the loop constructs.
2398+
2399+ Each `acc.loop` holds private and reduction operands which are the
2400+ ssa values from the corresponding `acc.private` or `acc.reduction`
2401+ operations. Additionally, firstprivate operands are supported to
2402+ represent cases where privatization is needed with initialization
2403+ from an original value. While the OpenACC specification does not
2404+ explicitly support firstprivate on loop constructs, this extension
2405+ enables representing privatization scenarios that arise from an
2406+ optimization and codegen pipeline operating on acc dialect.
2407+
2408+ The operation supports capturing information that it comes combined
2409+ constructs (e.g., `parallel loop`, `kernels loop`, `serial loop`)
2410+ through the `combined` attribute despite requiring the `acc.loop`
2411+ to be decomposed from the compute operation representing compute
2412+ construct.
23902413
23912414 Example:
23922415
23932416 ```mlir
2394- acc.loop gang() vector() (%arg3 : index, %arg4 : index, %arg5 : index) =
2417+ acc.loop gang() vector() (%arg3 : index, %arg4 : index, %arg5 : index) =
23952418 (%c0, %c0, %c0 : index, index, index) to
23962419 (%c10, %c10, %c10 : index, index, index) step
23972420 (%c1, %c1, %c1 : index, index, index) {
@@ -2400,10 +2423,12 @@ def OpenACC_LoopOp : OpenACC_Op<"loop",
24002423 } attributes { collapse = [3] }
24012424 ```
24022425
2403- `collapse`, `gang`, `worker`, `vector`, `seq`, `independent`, `auto` and
2404- `tile` operands are supported with `device_type` information. They should
2405- only be accessed by the extra provided getters. If modified, the
2406- corresponding `device_type` attributes must be modified as well.
2426+ `collapse`, `gang`, `worker`, `vector`, `seq`, `independent`, `auto`,
2427+ `cache`, and `tile` operands are supported with `device_type`
2428+ information. These clauses should only be accessed through the provided
2429+ device-type-aware getter methods. When modifying these operands, the
2430+ corresponding `device_type` attributes must be updated to maintain
2431+ consistency between operands and their target device types.
24072432 }];
24082433
24092434 let arguments = (ins
@@ -2433,6 +2458,8 @@ def OpenACC_LoopOp : OpenACC_Op<"loop",
24332458 Variadic<OpenACC_AnyPointerOrMappableType>:$cacheOperands,
24342459 Variadic<OpenACC_AnyPointerOrMappableType>:$privateOperands,
24352460 OptionalAttr<SymbolRefArrayAttr>:$privatizationRecipes,
2461+ Variadic<OpenACC_AnyPointerOrMappableType>:$firstprivateOperands,
2462+ OptionalAttr<SymbolRefArrayAttr>:$firstprivatizationRecipes,
24362463 Variadic<AnyType>:$reductionOperands,
24372464 OptionalAttr<SymbolRefArrayAttr>:$reductionRecipes,
24382465 OptionalAttr<OpenACC_CombinedConstructsAttr>:$combined
@@ -2589,6 +2616,10 @@ def OpenACC_LoopOp : OpenACC_Op<"loop",
25892616 /// Adds a private clause variable to this operation, including its recipe.
25902617 void addPrivatization(MLIRContext *, mlir::acc::PrivateOp op,
25912618 mlir::acc::PrivateRecipeOp recipe);
2619+ /// Adds a firstprivate clause variable to this operation, including its
2620+ /// recipe.
2621+ void addFirstPrivatization(MLIRContext *, mlir::acc::FirstprivateOp op,
2622+ mlir::acc::FirstprivateRecipeOp recipe);
25922623 /// Adds a reduction clause variable to this operation, including its
25932624 /// recipe.
25942625 void addReduction(MLIRContext *, mlir::acc::ReductionOp op,
@@ -2609,6 +2640,8 @@ def OpenACC_LoopOp : OpenACC_Op<"loop",
26092640 type($vectorOperands), $vectorOperandsDeviceType, $vector)
26102641 | `private` `(` custom<SymOperandList>(
26112642 $privateOperands, type($privateOperands), $privatizationRecipes) `)`
2643+ | `firstprivate` `(` custom<SymOperandList>($firstprivateOperands,
2644+ type($firstprivateOperands), $firstprivatizationRecipes) `)`
26122645 | `tile` `(` custom<DeviceTypeOperandsWithSegment>($tileOperands,
26132646 type($tileOperands), $tileOperandsDeviceType, $tileOperandsSegments)
26142647 `)`
@@ -2665,6 +2698,8 @@ def OpenACC_LoopOp : OpenACC_Op<"loop",
26652698 /*cacheOperands=*/{},
26662699 /*privateOperands=*/{},
26672700 /*privatizationRecipes=*/nullptr,
2701+ /*firstprivateOperands=*/{},
2702+ /*firstprivatizationRecipes=*/nullptr,
26682703 /*reductionOperands=*/{},
26692704 /*reductionRecipes=*/nullptr,
26702705 /*combined=*/nullptr);
0 commit comments