xref: /llvm-project/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp (revision cbcb7ad32e6faca1f4c0f2f436e6076774104e17)
14225e7faSValentin Clement //===- OpenACC.cpp - OpenACC MLIR Operations ------------------------------===//
24225e7faSValentin Clement //
34225e7faSValentin Clement // Part of the MLIR Project, under the Apache License v2.0 with LLVM Exceptions.
44225e7faSValentin Clement // See https://llvm.org/LICENSE.txt for license information.
54225e7faSValentin Clement // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64225e7faSValentin Clement //
74225e7faSValentin Clement // =============================================================================
84225e7faSValentin Clement 
94225e7faSValentin Clement #include "mlir/Dialect/OpenACC/OpenACC.h"
10c184dcb4SRazvan Lupusoru #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
11c184dcb4SRazvan Lupusoru #include "mlir/Dialect/LLVMIR/LLVMTypes.h"
12c184dcb4SRazvan Lupusoru #include "mlir/Dialect/MemRef/IR/MemRef.h"
134225e7faSValentin Clement #include "mlir/IR/Builders.h"
14a0eb794dSRazvan Lupusoru #include "mlir/IR/BuiltinAttributes.h"
1509f7a55fSRiver Riddle #include "mlir/IR/BuiltinTypes.h"
16aae51255SMogball #include "mlir/IR/DialectImplementation.h"
1765e7cd13SRiver Riddle #include "mlir/IR/Matchers.h"
184225e7faSValentin Clement #include "mlir/IR/OpImplementation.h"
19*cbcb7ad3SRazvan Lupusoru #include "mlir/Support/LLVM.h"
20aa4e6a60SValentin Clement #include "mlir/Transforms/DialectConversion.h"
21e456689fSValentin Clement (バレンタイン クレメン) #include "llvm/ADT/SmallSet.h"
22aae51255SMogball #include "llvm/ADT/TypeSwitch.h"
23a0eb794dSRazvan Lupusoru #include "llvm/Support/LogicalResult.h"
244225e7faSValentin Clement 
254225e7faSValentin Clement using namespace mlir;
264225e7faSValentin Clement using namespace acc;
274225e7faSValentin Clement 
28485cc55eSStella Laurenzo #include "mlir/Dialect/OpenACC/OpenACCOpsDialect.cpp.inc"
29c184dcb4SRazvan Lupusoru #include "mlir/Dialect/OpenACC/OpenACCOpsEnums.cpp.inc"
3026d92826Skhaki3 #include "mlir/Dialect/OpenACC/OpenACCOpsInterfaces.cpp.inc"
31c184dcb4SRazvan Lupusoru #include "mlir/Dialect/OpenACC/OpenACCTypeInterfaces.cpp.inc"
32d0413438SKareem Ergawy #include "mlir/Dialect/OpenACCMPCommon/Interfaces/OpenACCMPOpsInterfaces.cpp.inc"
33485cc55eSStella Laurenzo 
3461278ec3SRazvan Lupusoru namespace {
354983432fSChristian Ulmann struct MemRefPointerLikeModel
364983432fSChristian Ulmann     : public PointerLikeType::ExternalModel<MemRefPointerLikeModel,
374983432fSChristian Ulmann                                             MemRefType> {
3861278ec3SRazvan Lupusoru   Type getElementType(Type pointer) const {
394983432fSChristian Ulmann     return llvm::cast<MemRefType>(pointer).getElementType();
4061278ec3SRazvan Lupusoru   }
4161278ec3SRazvan Lupusoru };
424983432fSChristian Ulmann 
434983432fSChristian Ulmann struct LLVMPointerPointerLikeModel
444983432fSChristian Ulmann     : public PointerLikeType::ExternalModel<LLVMPointerPointerLikeModel,
454983432fSChristian Ulmann                                             LLVM::LLVMPointerType> {
464983432fSChristian Ulmann   Type getElementType(Type pointer) const { return Type(); }
474983432fSChristian Ulmann };
4861278ec3SRazvan Lupusoru } // namespace
4961278ec3SRazvan Lupusoru 
504225e7faSValentin Clement //===----------------------------------------------------------------------===//
514225e7faSValentin Clement // OpenACC operations
524225e7faSValentin Clement //===----------------------------------------------------------------------===//
534225e7faSValentin Clement 
544225e7faSValentin Clement void OpenACCDialect::initialize() {
554225e7faSValentin Clement   addOperations<
564225e7faSValentin Clement #define GET_OP_LIST
574225e7faSValentin Clement #include "mlir/Dialect/OpenACC/OpenACCOps.cpp.inc"
584225e7faSValentin Clement       >();
59aae51255SMogball   addAttributes<
60aae51255SMogball #define GET_ATTRDEF_LIST
61aae51255SMogball #include "mlir/Dialect/OpenACC/OpenACCOpsAttributes.cpp.inc"
62aae51255SMogball       >();
63c184dcb4SRazvan Lupusoru   addTypes<
64c184dcb4SRazvan Lupusoru #define GET_TYPEDEF_LIST
65c184dcb4SRazvan Lupusoru #include "mlir/Dialect/OpenACC/OpenACCOpsTypes.cpp.inc"
66c184dcb4SRazvan Lupusoru       >();
67c184dcb4SRazvan Lupusoru 
68c184dcb4SRazvan Lupusoru   // By attaching interfaces here, we make the OpenACC dialect dependent on
69c184dcb4SRazvan Lupusoru   // the other dialects. This is probably better than having dialects like LLVM
70c184dcb4SRazvan Lupusoru   // and memref be dependent on OpenACC.
714983432fSChristian Ulmann   MemRefType::attachInterface<MemRefPointerLikeModel>(*getContext());
724983432fSChristian Ulmann   LLVM::LLVMPointerType::attachInterface<LLVMPointerPointerLikeModel>(
734983432fSChristian Ulmann       *getContext());
74c184dcb4SRazvan Lupusoru }
75c184dcb4SRazvan Lupusoru 
76c184dcb4SRazvan Lupusoru //===----------------------------------------------------------------------===//
77ee6199caSValentin Clement (バレンタイン クレメン) // device_type support helpers
78ee6199caSValentin Clement (バレンタイン クレメン) //===----------------------------------------------------------------------===//
79ee6199caSValentin Clement (バレンタイン クレメン) 
80ee6199caSValentin Clement (バレンタイン クレメン) static bool hasDeviceTypeValues(std::optional<mlir::ArrayAttr> arrayAttr) {
81ee6199caSValentin Clement (バレンタイン クレメン)   if (arrayAttr && *arrayAttr && arrayAttr->size() > 0)
82ee6199caSValentin Clement (バレンタイン クレメン)     return true;
83ee6199caSValentin Clement (バレンタイン クレメン)   return false;
84ee6199caSValentin Clement (バレンタイン クレメン) }
85ee6199caSValentin Clement (バレンタイン クレメン) 
86ee6199caSValentin Clement (バレンタイン クレメン) static bool hasDeviceType(std::optional<mlir::ArrayAttr> arrayAttr,
87ee6199caSValentin Clement (バレンタイン クレメン)                           mlir::acc::DeviceType deviceType) {
88ee6199caSValentin Clement (バレンタイン クレメン)   if (!hasDeviceTypeValues(arrayAttr))
89ee6199caSValentin Clement (バレンタイン クレメン)     return false;
90ee6199caSValentin Clement (バレンタイン クレメン) 
91ee6199caSValentin Clement (バレンタイン クレメン)   for (auto attr : *arrayAttr) {
92ee6199caSValentin Clement (バレンタイン クレメン)     auto deviceTypeAttr = mlir::dyn_cast<mlir::acc::DeviceTypeAttr>(attr);
93ee6199caSValentin Clement (バレンタイン クレメン)     if (deviceTypeAttr.getValue() == deviceType)
94ee6199caSValentin Clement (バレンタイン クレメン)       return true;
95ee6199caSValentin Clement (バレンタイン クレメン)   }
96ee6199caSValentin Clement (バレンタイン クレメン) 
97ee6199caSValentin Clement (バレンタイン クレメン)   return false;
98ee6199caSValentin Clement (バレンタイン クレメン) }
99ee6199caSValentin Clement (バレンタイン クレメン) 
100ee6199caSValentin Clement (バレンタイン クレメン) static void printDeviceTypes(mlir::OpAsmPrinter &p,
101ee6199caSValentin Clement (バレンタイン クレメン)                              std::optional<mlir::ArrayAttr> deviceTypes) {
102ee6199caSValentin Clement (バレンタイン クレメン)   if (!hasDeviceTypeValues(deviceTypes))
103ee6199caSValentin Clement (バレンタイン クレメン)     return;
104ee6199caSValentin Clement (バレンタイン クレメン) 
105ee6199caSValentin Clement (バレンタイン クレメン)   p << "[";
106ee6199caSValentin Clement (バレンタイン クレメン)   llvm::interleaveComma(*deviceTypes, p,
107ee6199caSValentin Clement (バレンタイン クレメン)                         [&](mlir::Attribute attr) { p << attr; });
108ee6199caSValentin Clement (バレンタイン クレメン)   p << "]";
109ee6199caSValentin Clement (バレンタイン クレメン) }
110ee6199caSValentin Clement (バレンタイン クレメン) 
111c09dc2d9SValentin Clement (バレンタイン クレメン) static std::optional<unsigned> findSegment(ArrayAttr segments,
112c09dc2d9SValentin Clement (バレンタイン クレメン)                                            mlir::acc::DeviceType deviceType) {
113c09dc2d9SValentin Clement (バレンタイン クレメン)   unsigned segmentIdx = 0;
114c09dc2d9SValentin Clement (バレンタイン クレメン)   for (auto attr : segments) {
115c09dc2d9SValentin Clement (バレンタイン クレメン)     auto deviceTypeAttr = mlir::dyn_cast<mlir::acc::DeviceTypeAttr>(attr);
116c09dc2d9SValentin Clement (バレンタイン クレメン)     if (deviceTypeAttr.getValue() == deviceType)
117c09dc2d9SValentin Clement (バレンタイン クレメン)       return std::make_optional(segmentIdx);
118c09dc2d9SValentin Clement (バレンタイン クレメン)     ++segmentIdx;
119c09dc2d9SValentin Clement (バレンタイン クレメン)   }
120c09dc2d9SValentin Clement (バレンタイン クレメン)   return std::nullopt;
121c09dc2d9SValentin Clement (バレンタイン クレメン) }
122c09dc2d9SValentin Clement (バレンタイン クレメン) 
123c09dc2d9SValentin Clement (バレンタイン クレメン) static mlir::Operation::operand_range
124c09dc2d9SValentin Clement (バレンタイン クレメン) getValuesFromSegments(std::optional<mlir::ArrayAttr> arrayAttr,
125c09dc2d9SValentin Clement (バレンタイン クレメン)                       mlir::Operation::operand_range range,
126c09dc2d9SValentin Clement (バレンタイン クレメン)                       std::optional<llvm::ArrayRef<int32_t>> segments,
127c09dc2d9SValentin Clement (バレンタイン クレメン)                       mlir::acc::DeviceType deviceType) {
128c09dc2d9SValentin Clement (バレンタイン クレメン)   if (!arrayAttr)
129c09dc2d9SValentin Clement (バレンタイン クレメン)     return range.take_front(0);
130c09dc2d9SValentin Clement (バレンタイン クレメン)   if (auto pos = findSegment(*arrayAttr, deviceType)) {
131c09dc2d9SValentin Clement (バレンタイン クレメン)     int32_t nbOperandsBefore = 0;
132c09dc2d9SValentin Clement (バレンタイン クレメン)     for (unsigned i = 0; i < *pos; ++i)
133c09dc2d9SValentin Clement (バレンタイン クレメン)       nbOperandsBefore += (*segments)[i];
134c09dc2d9SValentin Clement (バレンタイン クレメン)     return range.drop_front(nbOperandsBefore).take_front((*segments)[*pos]);
135c09dc2d9SValentin Clement (バレンタイン クレメン)   }
136c09dc2d9SValentin Clement (バレンタイン クレメン)   return range.take_front(0);
137c09dc2d9SValentin Clement (バレンタイン クレメン) }
138c09dc2d9SValentin Clement (バレンタイン クレメン) 
139c09dc2d9SValentin Clement (バレンタイン クレメン) static mlir::Value
140c09dc2d9SValentin Clement (バレンタイン クレメン) getWaitDevnumValue(std::optional<mlir::ArrayAttr> deviceTypeAttr,
141c09dc2d9SValentin Clement (バレンタイン クレメン)                    mlir::Operation::operand_range operands,
142c09dc2d9SValentin Clement (バレンタイン クレメン)                    std::optional<llvm::ArrayRef<int32_t>> segments,
143c09dc2d9SValentin Clement (バレンタイン クレメン)                    std::optional<mlir::ArrayAttr> hasWaitDevnum,
144c09dc2d9SValentin Clement (バレンタイン クレメン)                    mlir::acc::DeviceType deviceType) {
145c09dc2d9SValentin Clement (バレンタイン クレメン)   if (!hasDeviceTypeValues(deviceTypeAttr))
146c09dc2d9SValentin Clement (バレンタイン クレメン)     return {};
147c09dc2d9SValentin Clement (バレンタイン クレメン)   if (auto pos = findSegment(*deviceTypeAttr, deviceType))
148c09dc2d9SValentin Clement (バレンタイン クレメン)     if (hasWaitDevnum->getValue()[*pos])
149c09dc2d9SValentin Clement (バレンタイン クレメン)       return getValuesFromSegments(deviceTypeAttr, operands, segments,
150c09dc2d9SValentin Clement (バレンタイン クレメン)                                    deviceType)
151c09dc2d9SValentin Clement (バレンタイン クレメン)           .front();
152c09dc2d9SValentin Clement (バレンタイン クレメン)   return {};
153c09dc2d9SValentin Clement (バレンタイン クレメン) }
154c09dc2d9SValentin Clement (バレンタイン クレメン) 
155c09dc2d9SValentin Clement (バレンタイン クレメン) static mlir::Operation::operand_range
156c09dc2d9SValentin Clement (バレンタイン クレメン) getWaitValuesWithoutDevnum(std::optional<mlir::ArrayAttr> deviceTypeAttr,
157c09dc2d9SValentin Clement (バレンタイン クレメン)                            mlir::Operation::operand_range operands,
158c09dc2d9SValentin Clement (バレンタイン クレメン)                            std::optional<llvm::ArrayRef<int32_t>> segments,
159c09dc2d9SValentin Clement (バレンタイン クレメン)                            std::optional<mlir::ArrayAttr> hasWaitDevnum,
160c09dc2d9SValentin Clement (バレンタイン クレメン)                            mlir::acc::DeviceType deviceType) {
161c09dc2d9SValentin Clement (バレンタイン クレメン)   auto range =
162c09dc2d9SValentin Clement (バレンタイン クレメン)       getValuesFromSegments(deviceTypeAttr, operands, segments, deviceType);
163c09dc2d9SValentin Clement (バレンタイン クレメン)   if (range.empty())
164c09dc2d9SValentin Clement (バレンタイン クレメン)     return range;
165c09dc2d9SValentin Clement (バレンタイン クレメン)   if (auto pos = findSegment(*deviceTypeAttr, deviceType)) {
166c09dc2d9SValentin Clement (バレンタイン クレメン)     if (hasWaitDevnum && *hasWaitDevnum) {
167c09dc2d9SValentin Clement (バレンタイン クレメン)       auto boolAttr = mlir::dyn_cast<mlir::BoolAttr>((*hasWaitDevnum)[*pos]);
168c09dc2d9SValentin Clement (バレンタイン クレメン)       if (boolAttr.getValue())
169c09dc2d9SValentin Clement (バレンタイン クレメン)         return range.drop_front(1); // first value is devnum
170c09dc2d9SValentin Clement (バレンタイン クレメン)     }
171c09dc2d9SValentin Clement (バレンタイン クレメン)   }
172c09dc2d9SValentin Clement (バレンタイン クレメン)   return range;
173c09dc2d9SValentin Clement (バレンタイン クレメン) }
174c09dc2d9SValentin Clement (バレンタイン クレメン) 
175c09dc2d9SValentin Clement (バレンタイン クレメン) template <typename Op>
176c09dc2d9SValentin Clement (バレンタイン クレメン) static LogicalResult checkWaitAndAsyncConflict(Op op) {
177c09dc2d9SValentin Clement (バレンタイン クレメン)   for (uint32_t dtypeInt = 0; dtypeInt != acc::getMaxEnumValForDeviceType();
178c09dc2d9SValentin Clement (バレンタイン クレメン)        ++dtypeInt) {
179c09dc2d9SValentin Clement (バレンタイン クレメン)     auto dtype = static_cast<acc::DeviceType>(dtypeInt);
180c09dc2d9SValentin Clement (バレンタイン クレメン) 
181c09dc2d9SValentin Clement (バレンタイン クレメン)     // The async attribute represent the async clause without value. Therefore
182c09dc2d9SValentin Clement (バレンタイン クレメン)     // the attribute and operand cannot appear at the same time.
183c09dc2d9SValentin Clement (バレンタイン クレメン)     if (hasDeviceType(op.getAsyncOperandsDeviceType(), dtype) &&
184c09dc2d9SValentin Clement (バレンタイン クレメン)         op.hasAsyncOnly(dtype))
185c09dc2d9SValentin Clement (バレンタイン クレメン)       return op.emitError("async attribute cannot appear with asyncOperand");
186c09dc2d9SValentin Clement (バレンタイン クレメン) 
187c09dc2d9SValentin Clement (バレンタイン クレメン)     // The wait attribute represent the wait clause without values. Therefore
188c09dc2d9SValentin Clement (バレンタイン クレメン)     // the attribute and operands cannot appear at the same time.
189c09dc2d9SValentin Clement (バレンタイン クレメン)     if (hasDeviceType(op.getWaitOperandsDeviceType(), dtype) &&
190c09dc2d9SValentin Clement (バレンタイン クレメン)         op.hasWaitOnly(dtype))
191c09dc2d9SValentin Clement (バレンタイン クレメン)       return op.emitError("wait attribute cannot appear with waitOperands");
192c09dc2d9SValentin Clement (バレンタイン クレメン)   }
193c09dc2d9SValentin Clement (バレンタイン クレメン)   return success();
194c09dc2d9SValentin Clement (バレンタイン クレメン) }
195c09dc2d9SValentin Clement (バレンタイン クレメン) 
196*cbcb7ad3SRazvan Lupusoru template <typename Op>
197*cbcb7ad3SRazvan Lupusoru static LogicalResult checkVarAndVarType(Op op) {
198*cbcb7ad3SRazvan Lupusoru   if (!op.getVar())
199*cbcb7ad3SRazvan Lupusoru     return op.emitError("must have var operand");
200*cbcb7ad3SRazvan Lupusoru 
201*cbcb7ad3SRazvan Lupusoru   if (mlir::isa<mlir::acc::PointerLikeType>(op.getVar().getType()) &&
202*cbcb7ad3SRazvan Lupusoru       mlir::isa<mlir::acc::MappableType>(op.getVar().getType())) {
203*cbcb7ad3SRazvan Lupusoru     // TODO: If a type implements both interfaces (mappable and pointer-like),
204*cbcb7ad3SRazvan Lupusoru     // it is unclear which semantics to apply without additional info which
205*cbcb7ad3SRazvan Lupusoru     // would need captured in the data operation. For now restrict this case
206*cbcb7ad3SRazvan Lupusoru     // unless a compelling reason to support disambiguating between the two.
207*cbcb7ad3SRazvan Lupusoru     return op.emitError("var must be mappable or pointer-like (not both)");
208*cbcb7ad3SRazvan Lupusoru   }
209*cbcb7ad3SRazvan Lupusoru 
210*cbcb7ad3SRazvan Lupusoru   if (!mlir::isa<mlir::acc::PointerLikeType>(op.getVar().getType()) &&
211*cbcb7ad3SRazvan Lupusoru       !mlir::isa<mlir::acc::MappableType>(op.getVar().getType()))
212*cbcb7ad3SRazvan Lupusoru     return op.emitError("var must be mappable or pointer-like");
213*cbcb7ad3SRazvan Lupusoru 
214*cbcb7ad3SRazvan Lupusoru   if (mlir::isa<mlir::acc::MappableType>(op.getVar().getType()) &&
215*cbcb7ad3SRazvan Lupusoru       op.getVarType() != op.getVar().getType())
216*cbcb7ad3SRazvan Lupusoru     return op.emitError("varType must match when var is mappable");
217*cbcb7ad3SRazvan Lupusoru 
218*cbcb7ad3SRazvan Lupusoru   return success();
219*cbcb7ad3SRazvan Lupusoru }
220*cbcb7ad3SRazvan Lupusoru 
221*cbcb7ad3SRazvan Lupusoru template <typename Op>
222*cbcb7ad3SRazvan Lupusoru static LogicalResult checkVarAndAccVar(Op op) {
223*cbcb7ad3SRazvan Lupusoru   if (op.getVar().getType() != op.getAccVar().getType())
224*cbcb7ad3SRazvan Lupusoru     return op.emitError("input and output types must match");
225*cbcb7ad3SRazvan Lupusoru 
226*cbcb7ad3SRazvan Lupusoru   return success();
227*cbcb7ad3SRazvan Lupusoru }
228*cbcb7ad3SRazvan Lupusoru 
229*cbcb7ad3SRazvan Lupusoru static ParseResult parseVar(mlir::OpAsmParser &parser,
230*cbcb7ad3SRazvan Lupusoru                             OpAsmParser::UnresolvedOperand &var) {
231*cbcb7ad3SRazvan Lupusoru   // Either `var` or `varPtr` keyword is required.
232*cbcb7ad3SRazvan Lupusoru   if (failed(parser.parseOptionalKeyword("varPtr"))) {
233*cbcb7ad3SRazvan Lupusoru     if (failed(parser.parseKeyword("var")))
234*cbcb7ad3SRazvan Lupusoru       return failure();
235*cbcb7ad3SRazvan Lupusoru   }
236*cbcb7ad3SRazvan Lupusoru   if (failed(parser.parseLParen()))
237*cbcb7ad3SRazvan Lupusoru     return failure();
238*cbcb7ad3SRazvan Lupusoru   if (failed(parser.parseOperand(var)))
239*cbcb7ad3SRazvan Lupusoru     return failure();
240*cbcb7ad3SRazvan Lupusoru 
241*cbcb7ad3SRazvan Lupusoru   return success();
242*cbcb7ad3SRazvan Lupusoru }
243*cbcb7ad3SRazvan Lupusoru 
244*cbcb7ad3SRazvan Lupusoru static void printVar(mlir::OpAsmPrinter &p, mlir::Operation *op,
245*cbcb7ad3SRazvan Lupusoru                      mlir::Value var) {
246*cbcb7ad3SRazvan Lupusoru   if (mlir::isa<mlir::acc::PointerLikeType>(var.getType()))
247*cbcb7ad3SRazvan Lupusoru     p << "varPtr(";
248*cbcb7ad3SRazvan Lupusoru   else
249*cbcb7ad3SRazvan Lupusoru     p << "var(";
250*cbcb7ad3SRazvan Lupusoru   p.printOperand(var);
251*cbcb7ad3SRazvan Lupusoru }
252*cbcb7ad3SRazvan Lupusoru 
253*cbcb7ad3SRazvan Lupusoru static ParseResult parseAccVar(mlir::OpAsmParser &parser,
254*cbcb7ad3SRazvan Lupusoru                                OpAsmParser::UnresolvedOperand &var,
255*cbcb7ad3SRazvan Lupusoru                                mlir::Type &accVarType) {
256*cbcb7ad3SRazvan Lupusoru   // Either `accVar` or `accPtr` keyword is required.
257*cbcb7ad3SRazvan Lupusoru   if (failed(parser.parseOptionalKeyword("accPtr"))) {
258*cbcb7ad3SRazvan Lupusoru     if (failed(parser.parseKeyword("accVar")))
259*cbcb7ad3SRazvan Lupusoru       return failure();
260*cbcb7ad3SRazvan Lupusoru   }
261*cbcb7ad3SRazvan Lupusoru   if (failed(parser.parseLParen()))
262*cbcb7ad3SRazvan Lupusoru     return failure();
263*cbcb7ad3SRazvan Lupusoru   if (failed(parser.parseOperand(var)))
264*cbcb7ad3SRazvan Lupusoru     return failure();
265*cbcb7ad3SRazvan Lupusoru   if (failed(parser.parseColon()))
266*cbcb7ad3SRazvan Lupusoru     return failure();
267*cbcb7ad3SRazvan Lupusoru   if (failed(parser.parseType(accVarType)))
268*cbcb7ad3SRazvan Lupusoru     return failure();
269*cbcb7ad3SRazvan Lupusoru   if (failed(parser.parseRParen()))
270*cbcb7ad3SRazvan Lupusoru     return failure();
271*cbcb7ad3SRazvan Lupusoru 
272*cbcb7ad3SRazvan Lupusoru   return success();
273*cbcb7ad3SRazvan Lupusoru }
274*cbcb7ad3SRazvan Lupusoru 
275*cbcb7ad3SRazvan Lupusoru static void printAccVar(mlir::OpAsmPrinter &p, mlir::Operation *op,
276*cbcb7ad3SRazvan Lupusoru                         mlir::Value accVar, mlir::Type accVarType) {
277*cbcb7ad3SRazvan Lupusoru   if (mlir::isa<mlir::acc::PointerLikeType>(accVar.getType()))
278*cbcb7ad3SRazvan Lupusoru     p << "accPtr(";
279*cbcb7ad3SRazvan Lupusoru   else
280*cbcb7ad3SRazvan Lupusoru     p << "accVar(";
281*cbcb7ad3SRazvan Lupusoru   p.printOperand(accVar);
282*cbcb7ad3SRazvan Lupusoru   p << " : ";
283*cbcb7ad3SRazvan Lupusoru   p.printType(accVarType);
284*cbcb7ad3SRazvan Lupusoru   p << ")";
285*cbcb7ad3SRazvan Lupusoru }
286*cbcb7ad3SRazvan Lupusoru 
287a0eb794dSRazvan Lupusoru static ParseResult parseVarPtrType(mlir::OpAsmParser &parser,
288a0eb794dSRazvan Lupusoru                                    mlir::Type &varPtrType,
289a0eb794dSRazvan Lupusoru                                    mlir::TypeAttr &varTypeAttr) {
290a0eb794dSRazvan Lupusoru   if (failed(parser.parseType(varPtrType)))
291a0eb794dSRazvan Lupusoru     return failure();
292a0eb794dSRazvan Lupusoru   if (failed(parser.parseRParen()))
293a0eb794dSRazvan Lupusoru     return failure();
294a0eb794dSRazvan Lupusoru 
295a0eb794dSRazvan Lupusoru   if (succeeded(parser.parseOptionalKeyword("varType"))) {
296a0eb794dSRazvan Lupusoru     if (failed(parser.parseLParen()))
297a0eb794dSRazvan Lupusoru       return failure();
298a0eb794dSRazvan Lupusoru     mlir::Type varType;
299a0eb794dSRazvan Lupusoru     if (failed(parser.parseType(varType)))
300a0eb794dSRazvan Lupusoru       return failure();
301a0eb794dSRazvan Lupusoru     varTypeAttr = mlir::TypeAttr::get(varType);
302a0eb794dSRazvan Lupusoru     if (failed(parser.parseRParen()))
303a0eb794dSRazvan Lupusoru       return failure();
304a0eb794dSRazvan Lupusoru   } else {
305a0eb794dSRazvan Lupusoru     // Set `varType` from the element type of the type of `varPtr`.
306*cbcb7ad3SRazvan Lupusoru     if (mlir::isa<mlir::acc::PointerLikeType>(varPtrType))
307a0eb794dSRazvan Lupusoru       varTypeAttr = mlir::TypeAttr::get(
308a0eb794dSRazvan Lupusoru           mlir::cast<mlir::acc::PointerLikeType>(varPtrType).getElementType());
309*cbcb7ad3SRazvan Lupusoru     else
310*cbcb7ad3SRazvan Lupusoru       varTypeAttr = mlir::TypeAttr::get(varPtrType);
311a0eb794dSRazvan Lupusoru   }
312a0eb794dSRazvan Lupusoru 
313a0eb794dSRazvan Lupusoru   return success();
314a0eb794dSRazvan Lupusoru }
315a0eb794dSRazvan Lupusoru 
316a0eb794dSRazvan Lupusoru static void printVarPtrType(mlir::OpAsmPrinter &p, mlir::Operation *op,
317a0eb794dSRazvan Lupusoru                             mlir::Type varPtrType, mlir::TypeAttr varTypeAttr) {
318a0eb794dSRazvan Lupusoru   p.printType(varPtrType);
319a0eb794dSRazvan Lupusoru   p << ")";
320a0eb794dSRazvan Lupusoru 
321a0eb794dSRazvan Lupusoru   // Print the `varType` only if it differs from the element type of
322a0eb794dSRazvan Lupusoru   // `varPtr`'s type.
323a0eb794dSRazvan Lupusoru   mlir::Type varType = varTypeAttr.getValue();
324*cbcb7ad3SRazvan Lupusoru   mlir::Type typeToCheckAgainst =
325*cbcb7ad3SRazvan Lupusoru       mlir::isa<mlir::acc::PointerLikeType>(varPtrType)
326*cbcb7ad3SRazvan Lupusoru           ? mlir::cast<mlir::acc::PointerLikeType>(varPtrType).getElementType()
327*cbcb7ad3SRazvan Lupusoru           : varPtrType;
328*cbcb7ad3SRazvan Lupusoru   if (typeToCheckAgainst != varType) {
329a0eb794dSRazvan Lupusoru     p << " varType(";
330a0eb794dSRazvan Lupusoru     p.printType(varType);
331a0eb794dSRazvan Lupusoru     p << ")";
332a0eb794dSRazvan Lupusoru   }
333a0eb794dSRazvan Lupusoru }
334a0eb794dSRazvan Lupusoru 
335ee6199caSValentin Clement (バレンタイン クレメン) //===----------------------------------------------------------------------===//
336c184dcb4SRazvan Lupusoru // DataBoundsOp
337c184dcb4SRazvan Lupusoru //===----------------------------------------------------------------------===//
338c184dcb4SRazvan Lupusoru LogicalResult acc::DataBoundsOp::verify() {
339c184dcb4SRazvan Lupusoru   auto extent = getExtent();
340c184dcb4SRazvan Lupusoru   auto upperbound = getUpperbound();
3418052c1e6SValentin Clement   if (!extent && !upperbound)
342c184dcb4SRazvan Lupusoru     return emitError("expected extent or upperbound.");
343c184dcb4SRazvan Lupusoru   return success();
344c184dcb4SRazvan Lupusoru }
345c184dcb4SRazvan Lupusoru 
346c184dcb4SRazvan Lupusoru //===----------------------------------------------------------------------===//
347cfba521dSValentin Clement // PrivateOp
348cfba521dSValentin Clement //===----------------------------------------------------------------------===//
349cfba521dSValentin Clement LogicalResult acc::PrivateOp::verify() {
350cfba521dSValentin Clement   if (getDataClause() != acc::DataClause::acc_private)
351cfba521dSValentin Clement     return emitError(
352cfba521dSValentin Clement         "data clause associated with private operation must match its intent");
353*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndVarType(*this)))
354*cbcb7ad3SRazvan Lupusoru     return failure();
355cfba521dSValentin Clement   return success();
356cfba521dSValentin Clement }
357cfba521dSValentin Clement 
358cfba521dSValentin Clement //===----------------------------------------------------------------------===//
3598fb247e2SValentin Clement // FirstprivateOp
3608fb247e2SValentin Clement //===----------------------------------------------------------------------===//
3618fb247e2SValentin Clement LogicalResult acc::FirstprivateOp::verify() {
3628fb247e2SValentin Clement   if (getDataClause() != acc::DataClause::acc_firstprivate)
3638fb247e2SValentin Clement     return emitError("data clause associated with firstprivate operation must "
3648fb247e2SValentin Clement                      "match its intent");
365*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndVarType(*this)))
366*cbcb7ad3SRazvan Lupusoru     return failure();
3678fb247e2SValentin Clement   return success();
3688fb247e2SValentin Clement }
3698fb247e2SValentin Clement 
3708fb247e2SValentin Clement //===----------------------------------------------------------------------===//
371cd91f3a6SValentin Clement // ReductionOp
372cd91f3a6SValentin Clement //===----------------------------------------------------------------------===//
373cd91f3a6SValentin Clement LogicalResult acc::ReductionOp::verify() {
374cd91f3a6SValentin Clement   if (getDataClause() != acc::DataClause::acc_reduction)
375cd91f3a6SValentin Clement     return emitError("data clause associated with reduction operation must "
376cd91f3a6SValentin Clement                      "match its intent");
377*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndVarType(*this)))
378*cbcb7ad3SRazvan Lupusoru     return failure();
379cd91f3a6SValentin Clement   return success();
380cd91f3a6SValentin Clement }
381cd91f3a6SValentin Clement 
382cd91f3a6SValentin Clement //===----------------------------------------------------------------------===//
383c184dcb4SRazvan Lupusoru // DevicePtrOp
384c184dcb4SRazvan Lupusoru //===----------------------------------------------------------------------===//
385c184dcb4SRazvan Lupusoru LogicalResult acc::DevicePtrOp::verify() {
3868052c1e6SValentin Clement   if (getDataClause() != acc::DataClause::acc_deviceptr)
387c184dcb4SRazvan Lupusoru     return emitError("data clause associated with deviceptr operation must "
388c184dcb4SRazvan Lupusoru                      "match its intent");
389*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndVarType(*this)))
390*cbcb7ad3SRazvan Lupusoru     return failure();
391*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndAccVar(*this)))
392*cbcb7ad3SRazvan Lupusoru     return failure();
393c184dcb4SRazvan Lupusoru   return success();
394c184dcb4SRazvan Lupusoru }
395c184dcb4SRazvan Lupusoru 
396c184dcb4SRazvan Lupusoru //===----------------------------------------------------------------------===//
397c184dcb4SRazvan Lupusoru // PresentOp
398c184dcb4SRazvan Lupusoru //===----------------------------------------------------------------------===//
399c184dcb4SRazvan Lupusoru LogicalResult acc::PresentOp::verify() {
4008052c1e6SValentin Clement   if (getDataClause() != acc::DataClause::acc_present)
401c184dcb4SRazvan Lupusoru     return emitError(
402c184dcb4SRazvan Lupusoru         "data clause associated with present operation must match its intent");
403*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndVarType(*this)))
404*cbcb7ad3SRazvan Lupusoru     return failure();
405*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndAccVar(*this)))
406*cbcb7ad3SRazvan Lupusoru     return failure();
407c184dcb4SRazvan Lupusoru   return success();
408c184dcb4SRazvan Lupusoru }
409c184dcb4SRazvan Lupusoru 
410c184dcb4SRazvan Lupusoru //===----------------------------------------------------------------------===//
411c184dcb4SRazvan Lupusoru // CopyinOp
412c184dcb4SRazvan Lupusoru //===----------------------------------------------------------------------===//
413c184dcb4SRazvan Lupusoru LogicalResult acc::CopyinOp::verify() {
41470bd2b8bSRazvan Lupusoru   // Test for all clauses this operation can be decomposed from:
415475938d1SValentin Clement   if (!getImplicit() && getDataClause() != acc::DataClause::acc_copyin &&
41670bd2b8bSRazvan Lupusoru       getDataClause() != acc::DataClause::acc_copyin_readonly &&
41762ae549fSRazvan Lupusoru       getDataClause() != acc::DataClause::acc_copy &&
41862ae549fSRazvan Lupusoru       getDataClause() != acc::DataClause::acc_reduction)
419c184dcb4SRazvan Lupusoru     return emitError(
42070bd2b8bSRazvan Lupusoru         "data clause associated with copyin operation must match its intent"
42170bd2b8bSRazvan Lupusoru         " or specify original clause this operation was decomposed from");
422*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndVarType(*this)))
423*cbcb7ad3SRazvan Lupusoru     return failure();
424*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndAccVar(*this)))
425*cbcb7ad3SRazvan Lupusoru     return failure();
426c184dcb4SRazvan Lupusoru   return success();
427c184dcb4SRazvan Lupusoru }
428c184dcb4SRazvan Lupusoru 
429c184dcb4SRazvan Lupusoru bool acc::CopyinOp::isCopyinReadonly() {
430c184dcb4SRazvan Lupusoru   return getDataClause() == acc::DataClause::acc_copyin_readonly;
431c184dcb4SRazvan Lupusoru }
432c184dcb4SRazvan Lupusoru 
433c184dcb4SRazvan Lupusoru //===----------------------------------------------------------------------===//
434c184dcb4SRazvan Lupusoru // CreateOp
435c184dcb4SRazvan Lupusoru //===----------------------------------------------------------------------===//
436c184dcb4SRazvan Lupusoru LogicalResult acc::CreateOp::verify() {
43770bd2b8bSRazvan Lupusoru   // Test for all clauses this operation can be decomposed from:
438c184dcb4SRazvan Lupusoru   if (getDataClause() != acc::DataClause::acc_create &&
43970bd2b8bSRazvan Lupusoru       getDataClause() != acc::DataClause::acc_create_zero &&
44070bd2b8bSRazvan Lupusoru       getDataClause() != acc::DataClause::acc_copyout &&
4418052c1e6SValentin Clement       getDataClause() != acc::DataClause::acc_copyout_zero)
442c184dcb4SRazvan Lupusoru     return emitError(
44370bd2b8bSRazvan Lupusoru         "data clause associated with create operation must match its intent"
44470bd2b8bSRazvan Lupusoru         " or specify original clause this operation was decomposed from");
445*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndVarType(*this)))
446*cbcb7ad3SRazvan Lupusoru     return failure();
447*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndAccVar(*this)))
448*cbcb7ad3SRazvan Lupusoru     return failure();
449c184dcb4SRazvan Lupusoru   return success();
450c184dcb4SRazvan Lupusoru }
451c184dcb4SRazvan Lupusoru 
452c184dcb4SRazvan Lupusoru bool acc::CreateOp::isCreateZero() {
45370bd2b8bSRazvan Lupusoru   // The zero modifier is encoded in the data clause.
45470bd2b8bSRazvan Lupusoru   return getDataClause() == acc::DataClause::acc_create_zero ||
45570bd2b8bSRazvan Lupusoru          getDataClause() == acc::DataClause::acc_copyout_zero;
456c184dcb4SRazvan Lupusoru }
457c184dcb4SRazvan Lupusoru 
458c184dcb4SRazvan Lupusoru //===----------------------------------------------------------------------===//
459c184dcb4SRazvan Lupusoru // NoCreateOp
460c184dcb4SRazvan Lupusoru //===----------------------------------------------------------------------===//
461c184dcb4SRazvan Lupusoru LogicalResult acc::NoCreateOp::verify() {
4628052c1e6SValentin Clement   if (getDataClause() != acc::DataClause::acc_no_create)
463c184dcb4SRazvan Lupusoru     return emitError("data clause associated with no_create operation must "
464c184dcb4SRazvan Lupusoru                      "match its intent");
465*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndVarType(*this)))
466*cbcb7ad3SRazvan Lupusoru     return failure();
467*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndAccVar(*this)))
468*cbcb7ad3SRazvan Lupusoru     return failure();
469c184dcb4SRazvan Lupusoru   return success();
470c184dcb4SRazvan Lupusoru }
471c184dcb4SRazvan Lupusoru 
472c184dcb4SRazvan Lupusoru //===----------------------------------------------------------------------===//
473c184dcb4SRazvan Lupusoru // AttachOp
474c184dcb4SRazvan Lupusoru //===----------------------------------------------------------------------===//
475c184dcb4SRazvan Lupusoru LogicalResult acc::AttachOp::verify() {
4768052c1e6SValentin Clement   if (getDataClause() != acc::DataClause::acc_attach)
477c184dcb4SRazvan Lupusoru     return emitError(
478c184dcb4SRazvan Lupusoru         "data clause associated with attach operation must match its intent");
479*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndVarType(*this)))
480*cbcb7ad3SRazvan Lupusoru     return failure();
481*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndAccVar(*this)))
482*cbcb7ad3SRazvan Lupusoru     return failure();
483c184dcb4SRazvan Lupusoru   return success();
484c184dcb4SRazvan Lupusoru }
485c184dcb4SRazvan Lupusoru 
486c184dcb4SRazvan Lupusoru //===----------------------------------------------------------------------===//
4877496177dSRazvan Lupusoru // DeclareDeviceResidentOp
488c184dcb4SRazvan Lupusoru //===----------------------------------------------------------------------===//
4897496177dSRazvan Lupusoru 
4907496177dSRazvan Lupusoru LogicalResult acc::DeclareDeviceResidentOp::verify() {
4917496177dSRazvan Lupusoru   if (getDataClause() != acc::DataClause::acc_declare_device_resident)
4927496177dSRazvan Lupusoru     return emitError("data clause associated with device_resident operation "
4937496177dSRazvan Lupusoru                      "must match its intent");
494*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndVarType(*this)))
495*cbcb7ad3SRazvan Lupusoru     return failure();
496*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndAccVar(*this)))
497*cbcb7ad3SRazvan Lupusoru     return failure();
4987496177dSRazvan Lupusoru   return success();
4997496177dSRazvan Lupusoru }
5007496177dSRazvan Lupusoru 
5017496177dSRazvan Lupusoru //===----------------------------------------------------------------------===//
5027496177dSRazvan Lupusoru // DeclareLinkOp
5037496177dSRazvan Lupusoru //===----------------------------------------------------------------------===//
5047496177dSRazvan Lupusoru 
5057496177dSRazvan Lupusoru LogicalResult acc::DeclareLinkOp::verify() {
5067496177dSRazvan Lupusoru   if (getDataClause() != acc::DataClause::acc_declare_link)
5077496177dSRazvan Lupusoru     return emitError(
5087496177dSRazvan Lupusoru         "data clause associated with link operation must match its intent");
509*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndVarType(*this)))
510*cbcb7ad3SRazvan Lupusoru     return failure();
511*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndAccVar(*this)))
512*cbcb7ad3SRazvan Lupusoru     return failure();
513c184dcb4SRazvan Lupusoru   return success();
514c184dcb4SRazvan Lupusoru }
515c184dcb4SRazvan Lupusoru 
516c184dcb4SRazvan Lupusoru //===----------------------------------------------------------------------===//
517c184dcb4SRazvan Lupusoru // CopyoutOp
518c184dcb4SRazvan Lupusoru //===----------------------------------------------------------------------===//
519c184dcb4SRazvan Lupusoru LogicalResult acc::CopyoutOp::verify() {
52070bd2b8bSRazvan Lupusoru   // Test for all clauses this operation can be decomposed from:
521c184dcb4SRazvan Lupusoru   if (getDataClause() != acc::DataClause::acc_copyout &&
52270bd2b8bSRazvan Lupusoru       getDataClause() != acc::DataClause::acc_copyout_zero &&
52362ae549fSRazvan Lupusoru       getDataClause() != acc::DataClause::acc_copy &&
52462ae549fSRazvan Lupusoru       getDataClause() != acc::DataClause::acc_reduction)
525c184dcb4SRazvan Lupusoru     return emitError(
52670bd2b8bSRazvan Lupusoru         "data clause associated with copyout operation must match its intent"
52770bd2b8bSRazvan Lupusoru         " or specify original clause this operation was decomposed from");
528*cbcb7ad3SRazvan Lupusoru   if (!getVar() || !getAccVar())
529c184dcb4SRazvan Lupusoru     return emitError("must have both host and device pointers");
530*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndVarType(*this)))
531*cbcb7ad3SRazvan Lupusoru     return failure();
532*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndAccVar(*this)))
533*cbcb7ad3SRazvan Lupusoru     return failure();
534c184dcb4SRazvan Lupusoru   return success();
535c184dcb4SRazvan Lupusoru }
536c184dcb4SRazvan Lupusoru 
537c184dcb4SRazvan Lupusoru bool acc::CopyoutOp::isCopyoutZero() {
538c184dcb4SRazvan Lupusoru   return getDataClause() == acc::DataClause::acc_copyout_zero;
539c184dcb4SRazvan Lupusoru }
540c184dcb4SRazvan Lupusoru 
541c184dcb4SRazvan Lupusoru //===----------------------------------------------------------------------===//
542c184dcb4SRazvan Lupusoru // DeleteOp
543c184dcb4SRazvan Lupusoru //===----------------------------------------------------------------------===//
544c184dcb4SRazvan Lupusoru LogicalResult acc::DeleteOp::verify() {
54570bd2b8bSRazvan Lupusoru   // Test for all clauses this operation can be decomposed from:
54670bd2b8bSRazvan Lupusoru   if (getDataClause() != acc::DataClause::acc_delete &&
54770bd2b8bSRazvan Lupusoru       getDataClause() != acc::DataClause::acc_create &&
5487496177dSRazvan Lupusoru       getDataClause() != acc::DataClause::acc_create_zero &&
5497496177dSRazvan Lupusoru       getDataClause() != acc::DataClause::acc_copyin &&
5507496177dSRazvan Lupusoru       getDataClause() != acc::DataClause::acc_copyin_readonly &&
5517496177dSRazvan Lupusoru       getDataClause() != acc::DataClause::acc_present &&
5527496177dSRazvan Lupusoru       getDataClause() != acc::DataClause::acc_declare_device_resident &&
5537496177dSRazvan Lupusoru       getDataClause() != acc::DataClause::acc_declare_link)
554c184dcb4SRazvan Lupusoru     return emitError(
55570bd2b8bSRazvan Lupusoru         "data clause associated with delete operation must match its intent"
55670bd2b8bSRazvan Lupusoru         " or specify original clause this operation was decomposed from");
557*cbcb7ad3SRazvan Lupusoru   if (!getAccVar())
558a711b042SRazvan Lupusoru     return emitError("must have device pointer");
559c184dcb4SRazvan Lupusoru   return success();
560c184dcb4SRazvan Lupusoru }
561c184dcb4SRazvan Lupusoru 
562c184dcb4SRazvan Lupusoru //===----------------------------------------------------------------------===//
563c184dcb4SRazvan Lupusoru // DetachOp
564c184dcb4SRazvan Lupusoru //===----------------------------------------------------------------------===//
565c184dcb4SRazvan Lupusoru LogicalResult acc::DetachOp::verify() {
56670bd2b8bSRazvan Lupusoru   // Test for all clauses this operation can be decomposed from:
56770bd2b8bSRazvan Lupusoru   if (getDataClause() != acc::DataClause::acc_detach &&
5688052c1e6SValentin Clement       getDataClause() != acc::DataClause::acc_attach)
569c184dcb4SRazvan Lupusoru     return emitError(
57070bd2b8bSRazvan Lupusoru         "data clause associated with detach operation must match its intent"
57170bd2b8bSRazvan Lupusoru         " or specify original clause this operation was decomposed from");
572*cbcb7ad3SRazvan Lupusoru   if (!getAccVar())
573a711b042SRazvan Lupusoru     return emitError("must have device pointer");
574c184dcb4SRazvan Lupusoru   return success();
5754225e7faSValentin Clement }
5764225e7faSValentin Clement 
577437bc564SValentin Clement //===----------------------------------------------------------------------===//
578437bc564SValentin Clement // HostOp
579437bc564SValentin Clement //===----------------------------------------------------------------------===//
580437bc564SValentin Clement LogicalResult acc::UpdateHostOp::verify() {
581437bc564SValentin Clement   // Test for all clauses this operation can be decomposed from:
582437bc564SValentin Clement   if (getDataClause() != acc::DataClause::acc_update_host &&
583437bc564SValentin Clement       getDataClause() != acc::DataClause::acc_update_self)
584437bc564SValentin Clement     return emitError(
585437bc564SValentin Clement         "data clause associated with host operation must match its intent"
586437bc564SValentin Clement         " or specify original clause this operation was decomposed from");
587*cbcb7ad3SRazvan Lupusoru   if (!getVar() || !getAccVar())
588437bc564SValentin Clement     return emitError("must have both host and device pointers");
589*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndVarType(*this)))
590*cbcb7ad3SRazvan Lupusoru     return failure();
591*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndAccVar(*this)))
592*cbcb7ad3SRazvan Lupusoru     return failure();
593437bc564SValentin Clement   return success();
594437bc564SValentin Clement }
595437bc564SValentin Clement 
596437bc564SValentin Clement //===----------------------------------------------------------------------===//
597437bc564SValentin Clement // DeviceOp
598437bc564SValentin Clement //===----------------------------------------------------------------------===//
599437bc564SValentin Clement LogicalResult acc::UpdateDeviceOp::verify() {
600437bc564SValentin Clement   // Test for all clauses this operation can be decomposed from:
601437bc564SValentin Clement   if (getDataClause() != acc::DataClause::acc_update_device)
602437bc564SValentin Clement     return emitError(
603437bc564SValentin Clement         "data clause associated with device operation must match its intent"
604437bc564SValentin Clement         " or specify original clause this operation was decomposed from");
605*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndVarType(*this)))
606*cbcb7ad3SRazvan Lupusoru     return failure();
607*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndAccVar(*this)))
608*cbcb7ad3SRazvan Lupusoru     return failure();
609437bc564SValentin Clement   return success();
610437bc564SValentin Clement }
611437bc564SValentin Clement 
6125cbe3381SValentin Clement //===----------------------------------------------------------------------===//
6135cbe3381SValentin Clement // UseDeviceOp
6145cbe3381SValentin Clement //===----------------------------------------------------------------------===//
6155cbe3381SValentin Clement LogicalResult acc::UseDeviceOp::verify() {
6165cbe3381SValentin Clement   // Test for all clauses this operation can be decomposed from:
6175cbe3381SValentin Clement   if (getDataClause() != acc::DataClause::acc_use_device)
6185cbe3381SValentin Clement     return emitError(
6195cbe3381SValentin Clement         "data clause associated with use_device operation must match its intent"
6205cbe3381SValentin Clement         " or specify original clause this operation was decomposed from");
621*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndVarType(*this)))
622*cbcb7ad3SRazvan Lupusoru     return failure();
623*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndAccVar(*this)))
624*cbcb7ad3SRazvan Lupusoru     return failure();
6255cbe3381SValentin Clement   return success();
6265cbe3381SValentin Clement }
6275cbe3381SValentin Clement 
628996171a4SValentin Clement (バレンタイン クレメン) //===----------------------------------------------------------------------===//
629996171a4SValentin Clement (バレンタイン クレメン) // CacheOp
630996171a4SValentin Clement (バレンタイン クレメン) //===----------------------------------------------------------------------===//
631996171a4SValentin Clement (バレンタイン クレメン) LogicalResult acc::CacheOp::verify() {
632996171a4SValentin Clement (バレンタイン クレメン)   // Test for all clauses this operation can be decomposed from:
633996171a4SValentin Clement (バレンタイン クレメン)   if (getDataClause() != acc::DataClause::acc_cache &&
634996171a4SValentin Clement (バレンタイン クレメン)       getDataClause() != acc::DataClause::acc_cache_readonly)
635996171a4SValentin Clement (バレンタイン クレメン)     return emitError(
636996171a4SValentin Clement (バレンタイン クレメン)         "data clause associated with cache operation must match its intent"
637996171a4SValentin Clement (バレンタイン クレメン)         " or specify original clause this operation was decomposed from");
638*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndVarType(*this)))
639*cbcb7ad3SRazvan Lupusoru     return failure();
640*cbcb7ad3SRazvan Lupusoru   if (failed(checkVarAndAccVar(*this)))
641*cbcb7ad3SRazvan Lupusoru     return failure();
642996171a4SValentin Clement (バレンタイン クレメン)   return success();
643996171a4SValentin Clement (バレンタイン クレメン) }
644996171a4SValentin Clement (バレンタイン クレメン) 
6454225e7faSValentin Clement template <typename StructureOp>
6464225e7faSValentin Clement static ParseResult parseRegions(OpAsmParser &parser, OperationState &state,
6474225e7faSValentin Clement                                 unsigned nRegions = 1) {
6484225e7faSValentin Clement 
6494225e7faSValentin Clement   SmallVector<Region *, 2> regions;
6504225e7faSValentin Clement   for (unsigned i = 0; i < nRegions; ++i)
6514225e7faSValentin Clement     regions.push_back(state.addRegion());
6524225e7faSValentin Clement 
6538052c1e6SValentin Clement   for (Region *region : regions)
6544225e7faSValentin Clement     if (parser.parseRegion(*region, /*arguments=*/{}, /*argTypes=*/{}))
6554225e7faSValentin Clement       return failure();
6564225e7faSValentin Clement 
6574225e7faSValentin Clement   return success();
6584225e7faSValentin Clement }
6594225e7faSValentin Clement 
6609c77350bSValentin Clement static bool isComputeOperation(Operation *op) {
661*cbcb7ad3SRazvan Lupusoru   return isa<ACC_COMPUTE_CONSTRUCT_AND_LOOP_OPS>(op);
6629c77350bSValentin Clement }
6639c77350bSValentin Clement 
664aa4e6a60SValentin Clement namespace {
665aa4e6a60SValentin Clement /// Pattern to remove operation without region that have constant false `ifCond`
666aa4e6a60SValentin Clement /// and remove the condition from the operation if the `ifCond` is a true
667aa4e6a60SValentin Clement /// constant.
668aa4e6a60SValentin Clement template <typename OpTy>
669aa4e6a60SValentin Clement struct RemoveConstantIfCondition : public OpRewritePattern<OpTy> {
670aa4e6a60SValentin Clement   using OpRewritePattern<OpTy>::OpRewritePattern;
671aa4e6a60SValentin Clement 
672aa4e6a60SValentin Clement   LogicalResult matchAndRewrite(OpTy op,
673aa4e6a60SValentin Clement                                 PatternRewriter &rewriter) const override {
674aa4e6a60SValentin Clement     // Early return if there is no condition.
675f9806b3eSRiver Riddle     Value ifCond = op.getIfCond();
67665e7cd13SRiver Riddle     if (!ifCond)
677e7790fbeSMatthias Springer       return failure();
678aa4e6a60SValentin Clement 
67965e7cd13SRiver Riddle     IntegerAttr constAttr;
680e7790fbeSMatthias Springer     if (!matchPattern(ifCond, m_Constant(&constAttr)))
681e7790fbeSMatthias Springer       return failure();
68265e7cd13SRiver Riddle     if (constAttr.getInt())
6835fcf907bSMatthias Springer       rewriter.modifyOpInPlace(op, [&]() { op.getIfCondMutable().erase(0); });
68465e7cd13SRiver Riddle     else
685aa4e6a60SValentin Clement       rewriter.eraseOp(op);
686aa4e6a60SValentin Clement 
687aa4e6a60SValentin Clement     return success();
688aa4e6a60SValentin Clement   }
689aa4e6a60SValentin Clement };
690c3c73e5dSValentin Clement 
691c3c73e5dSValentin Clement /// Replaces the given op with the contents of the given single-block region,
692c3c73e5dSValentin Clement /// using the operands of the block terminator to replace operation results.
693c3c73e5dSValentin Clement static void replaceOpWithRegion(PatternRewriter &rewriter, Operation *op,
694c3c73e5dSValentin Clement                                 Region &region, ValueRange blockArgs = {}) {
695c3c73e5dSValentin Clement   assert(llvm::hasSingleElement(region) && "expected single-region block");
696c3c73e5dSValentin Clement   Block *block = &region.front();
697c3c73e5dSValentin Clement   Operation *terminator = block->getTerminator();
698c3c73e5dSValentin Clement   ValueRange results = terminator->getOperands();
699c3c73e5dSValentin Clement   rewriter.inlineBlockBefore(block, op, blockArgs);
700c3c73e5dSValentin Clement   rewriter.replaceOp(op, results);
701c3c73e5dSValentin Clement   rewriter.eraseOp(terminator);
702c3c73e5dSValentin Clement }
703c3c73e5dSValentin Clement 
704c3c73e5dSValentin Clement /// Pattern to remove operation with region that have constant false `ifCond`
705c3c73e5dSValentin Clement /// and remove the condition from the operation if the `ifCond` is constant
706c3c73e5dSValentin Clement /// true.
707c3c73e5dSValentin Clement template <typename OpTy>
708c3c73e5dSValentin Clement struct RemoveConstantIfConditionWithRegion : public OpRewritePattern<OpTy> {
709c3c73e5dSValentin Clement   using OpRewritePattern<OpTy>::OpRewritePattern;
710c3c73e5dSValentin Clement 
711c3c73e5dSValentin Clement   LogicalResult matchAndRewrite(OpTy op,
712c3c73e5dSValentin Clement                                 PatternRewriter &rewriter) const override {
713c3c73e5dSValentin Clement     // Early return if there is no condition.
714c3c73e5dSValentin Clement     Value ifCond = op.getIfCond();
715c3c73e5dSValentin Clement     if (!ifCond)
716c3c73e5dSValentin Clement       return failure();
717c3c73e5dSValentin Clement 
718c3c73e5dSValentin Clement     IntegerAttr constAttr;
719c3c73e5dSValentin Clement     if (!matchPattern(ifCond, m_Constant(&constAttr)))
720c3c73e5dSValentin Clement       return failure();
721c3c73e5dSValentin Clement     if (constAttr.getInt())
7225fcf907bSMatthias Springer       rewriter.modifyOpInPlace(op, [&]() { op.getIfCondMutable().erase(0); });
723c3c73e5dSValentin Clement     else
724c3c73e5dSValentin Clement       replaceOpWithRegion(rewriter, op, op.getRegion());
725c3c73e5dSValentin Clement 
726c3c73e5dSValentin Clement     return success();
727c3c73e5dSValentin Clement   }
728c3c73e5dSValentin Clement };
729c3c73e5dSValentin Clement 
730aa4e6a60SValentin Clement } // namespace
731aa4e6a60SValentin Clement 
7324225e7faSValentin Clement //===----------------------------------------------------------------------===//
7339c3299b8SValentin Clement // PrivateRecipeOp
7349c3299b8SValentin Clement //===----------------------------------------------------------------------===//
7359c3299b8SValentin Clement 
73612f3ae6fSValentin Clement static LogicalResult verifyInitLikeSingleArgRegion(
73712f3ae6fSValentin Clement     Operation *op, Region &region, StringRef regionType, StringRef regionName,
73812f3ae6fSValentin Clement     Type type, bool verifyYield, bool optional = false) {
73912f3ae6fSValentin Clement   if (optional && region.empty())
7409c3299b8SValentin Clement     return success();
7419c3299b8SValentin Clement 
7428497dfdfSValentin Clement   if (region.empty())
7438497dfdfSValentin Clement     return op->emitOpError() << "expects non-empty " << regionName << " region";
7448497dfdfSValentin Clement   Block &firstBlock = region.front();
7451d498342SValentin Clement   if (firstBlock.getNumArguments() < 1 ||
74612f3ae6fSValentin Clement       firstBlock.getArgument(0).getType() != type)
7478497dfdfSValentin Clement     return op->emitOpError() << "expects " << regionName
7481d498342SValentin Clement                              << " region first "
74912f3ae6fSValentin Clement                                 "argument of the "
75012f3ae6fSValentin Clement                              << regionType << " type";
7518497dfdfSValentin Clement 
7528497dfdfSValentin Clement   if (verifyYield) {
7538497dfdfSValentin Clement     for (YieldOp yieldOp : region.getOps<acc::YieldOp>()) {
7548497dfdfSValentin Clement       if (yieldOp.getOperands().size() != 1 ||
7558497dfdfSValentin Clement           yieldOp.getOperands().getTypes()[0] != type)
7568497dfdfSValentin Clement         return op->emitOpError() << "expects " << regionName
7578497dfdfSValentin Clement                                  << " region to "
75812f3ae6fSValentin Clement                                     "yield a value of the "
75912f3ae6fSValentin Clement                                  << regionType << " type";
7608497dfdfSValentin Clement     }
7618497dfdfSValentin Clement   }
7628497dfdfSValentin Clement   return success();
7638497dfdfSValentin Clement }
7648497dfdfSValentin Clement 
7658497dfdfSValentin Clement LogicalResult acc::PrivateRecipeOp::verifyRegions() {
76612f3ae6fSValentin Clement   if (failed(verifyInitLikeSingleArgRegion(*this, getInitRegion(),
76712f3ae6fSValentin Clement                                            "privatization", "init", getType(),
768470b6527SValentin Clement                                            /*verifyYield=*/false)))
7698497dfdfSValentin Clement     return failure();
77012f3ae6fSValentin Clement   if (failed(verifyInitLikeSingleArgRegion(
77112f3ae6fSValentin Clement           *this, getDestroyRegion(), "privatization", "destroy", getType(),
77212f3ae6fSValentin Clement           /*verifyYield=*/false, /*optional=*/true)))
7738497dfdfSValentin Clement     return failure();
7748497dfdfSValentin Clement   return success();
7758497dfdfSValentin Clement }
7768497dfdfSValentin Clement 
7778497dfdfSValentin Clement //===----------------------------------------------------------------------===//
7788497dfdfSValentin Clement // FirstprivateRecipeOp
7798497dfdfSValentin Clement //===----------------------------------------------------------------------===//
7808497dfdfSValentin Clement 
7818497dfdfSValentin Clement LogicalResult acc::FirstprivateRecipeOp::verifyRegions() {
78212f3ae6fSValentin Clement   if (failed(verifyInitLikeSingleArgRegion(*this, getInitRegion(),
78312f3ae6fSValentin Clement                                            "privatization", "init", getType(),
784d9568bd4SValentin Clement (バレンタイン クレメン)                                            /*verifyYield=*/false)))
7858497dfdfSValentin Clement     return failure();
7868497dfdfSValentin Clement 
78712f3ae6fSValentin Clement   if (getCopyRegion().empty())
78812f3ae6fSValentin Clement     return emitOpError() << "expects non-empty copy region";
78912f3ae6fSValentin Clement 
79012f3ae6fSValentin Clement   Block &firstBlock = getCopyRegion().front();
791e2f493beSValentin Clement (バレンタイン クレメン)   if (firstBlock.getNumArguments() < 2 ||
79212f3ae6fSValentin Clement       firstBlock.getArgument(0).getType() != getType())
79312f3ae6fSValentin Clement     return emitOpError() << "expects copy region with two arguments of the "
79412f3ae6fSValentin Clement                             "privatization type";
79512f3ae6fSValentin Clement 
7966a3312f3SValentin Clement   if (getDestroyRegion().empty())
7976a3312f3SValentin Clement     return success();
7986a3312f3SValentin Clement 
79912f3ae6fSValentin Clement   if (failed(verifyInitLikeSingleArgRegion(*this, getDestroyRegion(),
80012f3ae6fSValentin Clement                                            "privatization", "destroy",
80112f3ae6fSValentin Clement                                            getType(), /*verifyYield=*/false)))
8028497dfdfSValentin Clement     return failure();
80312f3ae6fSValentin Clement 
80412f3ae6fSValentin Clement   return success();
80512f3ae6fSValentin Clement }
80612f3ae6fSValentin Clement 
80712f3ae6fSValentin Clement //===----------------------------------------------------------------------===//
80812f3ae6fSValentin Clement // ReductionRecipeOp
80912f3ae6fSValentin Clement //===----------------------------------------------------------------------===//
81012f3ae6fSValentin Clement 
81112f3ae6fSValentin Clement LogicalResult acc::ReductionRecipeOp::verifyRegions() {
81212f3ae6fSValentin Clement   if (failed(verifyInitLikeSingleArgRegion(*this, getInitRegion(), "reduction",
81312f3ae6fSValentin Clement                                            "init", getType(),
814ff86ce65SValentin Clement                                            /*verifyYield=*/false)))
8158497dfdfSValentin Clement     return failure();
81612f3ae6fSValentin Clement 
81712f3ae6fSValentin Clement   if (getCombinerRegion().empty())
81812f3ae6fSValentin Clement     return emitOpError() << "expects non-empty combiner region";
81912f3ae6fSValentin Clement 
82012f3ae6fSValentin Clement   Block &reductionBlock = getCombinerRegion().front();
8211d498342SValentin Clement   if (reductionBlock.getNumArguments() < 2 ||
82212f3ae6fSValentin Clement       reductionBlock.getArgument(0).getType() != getType() ||
82312f3ae6fSValentin Clement       reductionBlock.getArgument(1).getType() != getType())
8241d498342SValentin Clement     return emitOpError() << "expects combiner region with the first two "
8251d498342SValentin Clement                          << "arguments of the reduction type";
82612f3ae6fSValentin Clement 
82712f3ae6fSValentin Clement   for (YieldOp yieldOp : getCombinerRegion().getOps<YieldOp>()) {
82812f3ae6fSValentin Clement     if (yieldOp.getOperands().size() != 1 ||
82912f3ae6fSValentin Clement         yieldOp.getOperands().getTypes()[0] != getType())
83012f3ae6fSValentin Clement       return emitOpError() << "expects combiner region to yield a value "
83112f3ae6fSValentin Clement                               "of the reduction type";
83212f3ae6fSValentin Clement   }
83312f3ae6fSValentin Clement 
8349c3299b8SValentin Clement   return success();
8359c3299b8SValentin Clement }
8369c3299b8SValentin Clement 
8379c3299b8SValentin Clement //===----------------------------------------------------------------------===//
838c067c6e5SValentin Clement // Custom parser and printer verifier for private clause
839c067c6e5SValentin Clement //===----------------------------------------------------------------------===//
840c067c6e5SValentin Clement 
841f4f53f8bSValentin Clement static ParseResult parseSymOperandList(
842c067c6e5SValentin Clement     mlir::OpAsmParser &parser,
843c067c6e5SValentin Clement     llvm::SmallVectorImpl<mlir::OpAsmParser::UnresolvedOperand> &operands,
844f4f53f8bSValentin Clement     llvm::SmallVectorImpl<Type> &types, mlir::ArrayAttr &symbols) {
845f4f53f8bSValentin Clement   llvm::SmallVector<SymbolRefAttr> attributes;
846c067c6e5SValentin Clement   if (failed(parser.parseCommaSeparatedList([&]() {
847f4f53f8bSValentin Clement         if (parser.parseAttribute(attributes.emplace_back()) ||
848c067c6e5SValentin Clement             parser.parseArrow() ||
849c067c6e5SValentin Clement             parser.parseOperand(operands.emplace_back()) ||
850c067c6e5SValentin Clement             parser.parseColonType(types.emplace_back()))
851c067c6e5SValentin Clement           return failure();
852c067c6e5SValentin Clement         return success();
853c067c6e5SValentin Clement       })))
854c067c6e5SValentin Clement     return failure();
855f4f53f8bSValentin Clement   llvm::SmallVector<mlir::Attribute> arrayAttr(attributes.begin(),
856f4f53f8bSValentin Clement                                                attributes.end());
857f4f53f8bSValentin Clement   symbols = ArrayAttr::get(parser.getContext(), arrayAttr);
858c067c6e5SValentin Clement   return success();
859c067c6e5SValentin Clement }
860c067c6e5SValentin Clement 
861f4f53f8bSValentin Clement static void printSymOperandList(mlir::OpAsmPrinter &p, mlir::Operation *op,
862f4f53f8bSValentin Clement                                 mlir::OperandRange operands,
863f4f53f8bSValentin Clement                                 mlir::TypeRange types,
864f4f53f8bSValentin Clement                                 std::optional<mlir::ArrayAttr> attributes) {
865bd5d41a3SValentin Clement (バレンタイン クレメン)   llvm::interleaveComma(llvm::zip(*attributes, operands), p, [&](auto it) {
866bd5d41a3SValentin Clement (バレンタイン クレメン)     p << std::get<0>(it) << " -> " << std::get<1>(it) << " : "
867bd5d41a3SValentin Clement (バレンタイン クレメン)       << std::get<1>(it).getType();
868bd5d41a3SValentin Clement (バレンタイン クレメン)   });
869c067c6e5SValentin Clement }
870c067c6e5SValentin Clement 
871c067c6e5SValentin Clement //===----------------------------------------------------------------------===//
8724225e7faSValentin Clement // ParallelOp
8734225e7faSValentin Clement //===----------------------------------------------------------------------===//
8744225e7faSValentin Clement 
875aad53e3bSValentin Clement /// Check dataOperands for acc.parallel, acc.serial and acc.kernels.
876aad53e3bSValentin Clement template <typename Op>
877aad53e3bSValentin Clement static LogicalResult checkDataOperands(Op op,
878aad53e3bSValentin Clement                                        const mlir::ValueRange &operands) {
879aad53e3bSValentin Clement   for (mlir::Value operand : operands)
880aad53e3bSValentin Clement     if (!mlir::isa<acc::AttachOp, acc::CopyinOp, acc::CopyoutOp, acc::CreateOp,
881aad53e3bSValentin Clement                    acc::DeleteOp, acc::DetachOp, acc::DevicePtrOp,
882aad53e3bSValentin Clement                    acc::GetDevicePtrOp, acc::NoCreateOp, acc::PresentOp>(
883aad53e3bSValentin Clement             operand.getDefiningOp()))
884aad53e3bSValentin Clement       return op.emitError(
885aad53e3bSValentin Clement           "expect data entry/exit operation or acc.getdeviceptr "
886aad53e3bSValentin Clement           "as defining op");
887aad53e3bSValentin Clement   return success();
888aad53e3bSValentin Clement }
889aad53e3bSValentin Clement 
890f4f53f8bSValentin Clement template <typename Op>
891c067c6e5SValentin Clement static LogicalResult
892f4f53f8bSValentin Clement checkSymOperandList(Operation *op, std::optional<mlir::ArrayAttr> attributes,
893f4f53f8bSValentin Clement                     mlir::OperandRange operands, llvm::StringRef operandName,
89459ceb7ddSValentin Clement                     llvm::StringRef symbolName, bool checkOperandType = true) {
895f4f53f8bSValentin Clement   if (!operands.empty()) {
896f4f53f8bSValentin Clement     if (!attributes || attributes->size() != operands.size())
897f4f53f8bSValentin Clement       return op->emitOpError()
898f4f53f8bSValentin Clement              << "expected as many " << symbolName << " symbol reference as "
899f4f53f8bSValentin Clement              << operandName << " operands";
900c067c6e5SValentin Clement   } else {
901f4f53f8bSValentin Clement     if (attributes)
902f4f53f8bSValentin Clement       return op->emitOpError()
903f4f53f8bSValentin Clement              << "unexpected " << symbolName << " symbol reference";
904c067c6e5SValentin Clement     return success();
905c067c6e5SValentin Clement   }
906c067c6e5SValentin Clement 
907f4f53f8bSValentin Clement   llvm::DenseSet<Value> set;
908f4f53f8bSValentin Clement   for (auto args : llvm::zip(operands, *attributes)) {
909f4f53f8bSValentin Clement     mlir::Value operand = std::get<0>(args);
910c067c6e5SValentin Clement 
911f4f53f8bSValentin Clement     if (!set.insert(operand).second)
912f4f53f8bSValentin Clement       return op->emitOpError()
913f4f53f8bSValentin Clement              << operandName << " operand appears more than once";
914c067c6e5SValentin Clement 
915f4f53f8bSValentin Clement     mlir::Type varType = operand.getType();
91668f58812STres Popp     auto symbolRef = llvm::cast<SymbolRefAttr>(std::get<1>(args));
917f4f53f8bSValentin Clement     auto decl = SymbolTable::lookupNearestSymbolFrom<Op>(op, symbolRef);
918c067c6e5SValentin Clement     if (!decl)
919f4f53f8bSValentin Clement       return op->emitOpError()
920f4f53f8bSValentin Clement              << "expected symbol reference " << symbolRef << " to point to a "
921f4f53f8bSValentin Clement              << operandName << " declaration";
922c067c6e5SValentin Clement 
92359ceb7ddSValentin Clement     if (checkOperandType && decl.getType() && decl.getType() != varType)
924a7a4bb69SValentin Clement       return op->emitOpError() << "expected " << operandName << " (" << varType
925a7a4bb69SValentin Clement                                << ") to be the same type as " << operandName
926a7a4bb69SValentin Clement                                << " declaration (" << decl.getType() << ")";
927c067c6e5SValentin Clement   }
928c067c6e5SValentin Clement 
929c067c6e5SValentin Clement   return success();
930c067c6e5SValentin Clement }
931c067c6e5SValentin Clement 
932cfcdebafSValentin Clement unsigned ParallelOp::getNumDataOperands() {
933c0a15970SRazvan Lupusoru   return getReductionOperands().size() + getPrivateOperands().size() +
934c0a15970SRazvan Lupusoru          getFirstprivateOperands().size() + getDataClauseOperands().size();
935cfcdebafSValentin Clement }
936cfcdebafSValentin Clement 
937cfcdebafSValentin Clement Value ParallelOp::getDataOperand(unsigned i) {
938c09dc2d9SValentin Clement (バレンタイン クレメン)   unsigned numOptional = getAsyncOperands().size();
939c4a63b8eSValentin Clement   numOptional += getNumGangs().size();
940a25da1a9SValentin Clement   numOptional += getNumWorkers().size();
941a25da1a9SValentin Clement   numOptional += getVectorLength().size();
942f9806b3eSRiver Riddle   numOptional += getIfCond() ? 1 : 0;
943f9806b3eSRiver Riddle   numOptional += getSelfCond() ? 1 : 0;
944f9806b3eSRiver Riddle   return getOperand(getWaitOperands().size() + numOptional + i);
945cfcdebafSValentin Clement }
946cfcdebafSValentin Clement 
947a25da1a9SValentin Clement template <typename Op>
948a25da1a9SValentin Clement static LogicalResult verifyDeviceTypeCountMatch(Op op, OperandRange operands,
949a25da1a9SValentin Clement                                                 ArrayAttr deviceTypes,
950a25da1a9SValentin Clement                                                 llvm::StringRef keyword) {
951baf8a39aSAdrian Kuegel   if (!operands.empty() && deviceTypes.getValue().size() != operands.size())
952a25da1a9SValentin Clement     return op.emitOpError() << keyword << " operands count must match "
953a25da1a9SValentin Clement                             << keyword << " device_type count";
954a25da1a9SValentin Clement   return success();
955a25da1a9SValentin Clement }
956a25da1a9SValentin Clement 
957a25da1a9SValentin Clement template <typename Op>
958a25da1a9SValentin Clement static LogicalResult verifyDeviceTypeAndSegmentCountMatch(
959a25da1a9SValentin Clement     Op op, OperandRange operands, DenseI32ArrayAttr segments,
960a25da1a9SValentin Clement     ArrayAttr deviceTypes, llvm::StringRef keyword, int32_t maxInSegment = 0) {
961a25da1a9SValentin Clement   std::size_t numOperandsInSegments = 0;
96265bd5ed8SValentin Clement (バレンタイン クレメン)   std::size_t nbOfSegments = 0;
963a25da1a9SValentin Clement 
96465bd5ed8SValentin Clement (バレンタイン クレメン)   if (segments) {
965a25da1a9SValentin Clement     for (auto segCount : segments.asArrayRef()) {
966a25da1a9SValentin Clement       if (maxInSegment != 0 && segCount > maxInSegment)
967a25da1a9SValentin Clement         return op.emitOpError() << keyword << " expects a maximum of "
968a25da1a9SValentin Clement                                 << maxInSegment << " values per segment";
969a25da1a9SValentin Clement       numOperandsInSegments += segCount;
97065bd5ed8SValentin Clement (バレンタイン クレメン)       ++nbOfSegments;
971a25da1a9SValentin Clement     }
97265bd5ed8SValentin Clement (バレンタイン クレメン)   }
97365bd5ed8SValentin Clement (バレンタイン クレメン) 
97465bd5ed8SValentin Clement (バレンタイン クレメン)   if ((numOperandsInSegments != operands.size()) ||
97565bd5ed8SValentin Clement (バレンタイン クレメン)       (!deviceTypes && !operands.empty()))
976a25da1a9SValentin Clement     return op.emitOpError()
977a25da1a9SValentin Clement            << keyword << " operand count does not match count in segments";
97865bd5ed8SValentin Clement (バレンタイン クレメン)   if (deviceTypes && deviceTypes.getValue().size() != nbOfSegments)
979a25da1a9SValentin Clement     return op.emitOpError()
980a25da1a9SValentin Clement            << keyword << " segment count does not match device_type count";
981a25da1a9SValentin Clement   return success();
982a25da1a9SValentin Clement }
983a25da1a9SValentin Clement 
984aad53e3bSValentin Clement LogicalResult acc::ParallelOp::verify() {
985f4f53f8bSValentin Clement   if (failed(checkSymOperandList<mlir::acc::PrivateRecipeOp>(
986c0a15970SRazvan Lupusoru           *this, getPrivatizations(), getPrivateOperands(), "private",
98726b2b5a5SValentin Clement (バレンタイン クレメン)           "privatizations", /*checkOperandType=*/false)))
988f4f53f8bSValentin Clement     return failure();
989c0a15970SRazvan Lupusoru   if (failed(checkSymOperandList<mlir::acc::FirstprivateRecipeOp>(
990c0a15970SRazvan Lupusoru           *this, getFirstprivatizations(), getFirstprivateOperands(),
991c0a15970SRazvan Lupusoru           "firstprivate", "firstprivatizations", /*checkOperandType=*/false)))
992c0a15970SRazvan Lupusoru     return failure();
993f4f53f8bSValentin Clement   if (failed(checkSymOperandList<mlir::acc::ReductionRecipeOp>(
994f4f53f8bSValentin Clement           *this, getReductionRecipes(), getReductionOperands(), "reduction",
9955e3faa05SRazvan Lupusoru           "reductions", false)))
996c067c6e5SValentin Clement     return failure();
997a25da1a9SValentin Clement 
998a25da1a9SValentin Clement   if (failed(verifyDeviceTypeAndSegmentCountMatch(
999a25da1a9SValentin Clement           *this, getNumGangs(), getNumGangsSegmentsAttr(),
1000a25da1a9SValentin Clement           getNumGangsDeviceTypeAttr(), "num_gangs", 3)))
1001a25da1a9SValentin Clement     return failure();
1002a25da1a9SValentin Clement 
1003a25da1a9SValentin Clement   if (failed(verifyDeviceTypeAndSegmentCountMatch(
1004a25da1a9SValentin Clement           *this, getWaitOperands(), getWaitOperandsSegmentsAttr(),
1005a25da1a9SValentin Clement           getWaitOperandsDeviceTypeAttr(), "wait")))
1006a25da1a9SValentin Clement     return failure();
1007a25da1a9SValentin Clement 
1008a25da1a9SValentin Clement   if (failed(verifyDeviceTypeCountMatch(*this, getNumWorkers(),
1009a25da1a9SValentin Clement                                         getNumWorkersDeviceTypeAttr(),
1010a25da1a9SValentin Clement                                         "num_workers")))
1011a25da1a9SValentin Clement     return failure();
1012a25da1a9SValentin Clement 
1013a25da1a9SValentin Clement   if (failed(verifyDeviceTypeCountMatch(*this, getVectorLength(),
1014a25da1a9SValentin Clement                                         getVectorLengthDeviceTypeAttr(),
1015a25da1a9SValentin Clement                                         "vector_length")))
1016a25da1a9SValentin Clement     return failure();
1017a25da1a9SValentin Clement 
1018c09dc2d9SValentin Clement (バレンタイン クレメン)   if (failed(verifyDeviceTypeCountMatch(*this, getAsyncOperands(),
1019c09dc2d9SValentin Clement (バレンタイン クレメン)                                         getAsyncOperandsDeviceTypeAttr(),
1020c09dc2d9SValentin Clement (バレンタイン クレメン)                                         "async")))
1021c09dc2d9SValentin Clement (バレンタイン クレメン)     return failure();
1022c09dc2d9SValentin Clement (バレンタイン クレメン) 
1023c09dc2d9SValentin Clement (バレンタイン クレメン)   if (failed(checkWaitAndAsyncConflict<acc::ParallelOp>(*this)))
1024a25da1a9SValentin Clement     return failure();
1025a25da1a9SValentin Clement 
1026aad53e3bSValentin Clement   return checkDataOperands<acc::ParallelOp>(*this, getDataClauseOperands());
1027aad53e3bSValentin Clement }
1028aad53e3bSValentin Clement 
1029a25da1a9SValentin Clement static mlir::Value
1030a25da1a9SValentin Clement getValueInDeviceTypeSegment(std::optional<mlir::ArrayAttr> arrayAttr,
1031a25da1a9SValentin Clement                             mlir::Operation::operand_range range,
1032a25da1a9SValentin Clement                             mlir::acc::DeviceType deviceType) {
1033a25da1a9SValentin Clement   if (!arrayAttr)
1034a25da1a9SValentin Clement     return {};
1035a25da1a9SValentin Clement   if (auto pos = findSegment(*arrayAttr, deviceType))
1036a25da1a9SValentin Clement     return range[*pos];
1037a25da1a9SValentin Clement   return {};
1038a25da1a9SValentin Clement }
1039a25da1a9SValentin Clement 
1040a25da1a9SValentin Clement bool acc::ParallelOp::hasAsyncOnly() {
1041a25da1a9SValentin Clement   return hasAsyncOnly(mlir::acc::DeviceType::None);
1042a25da1a9SValentin Clement }
1043a25da1a9SValentin Clement 
1044a25da1a9SValentin Clement bool acc::ParallelOp::hasAsyncOnly(mlir::acc::DeviceType deviceType) {
1045ee6199caSValentin Clement (バレンタイン クレメン)   return hasDeviceType(getAsyncOnly(), deviceType);
1046a25da1a9SValentin Clement }
1047a25da1a9SValentin Clement 
1048a25da1a9SValentin Clement mlir::Value acc::ParallelOp::getAsyncValue() {
1049a25da1a9SValentin Clement   return getAsyncValue(mlir::acc::DeviceType::None);
1050a25da1a9SValentin Clement }
1051a25da1a9SValentin Clement 
1052a25da1a9SValentin Clement mlir::Value acc::ParallelOp::getAsyncValue(mlir::acc::DeviceType deviceType) {
1053c09dc2d9SValentin Clement (バレンタイン クレメン)   return getValueInDeviceTypeSegment(getAsyncOperandsDeviceType(),
1054c09dc2d9SValentin Clement (バレンタイン クレメン)                                      getAsyncOperands(), deviceType);
1055a25da1a9SValentin Clement }
1056a25da1a9SValentin Clement 
1057a25da1a9SValentin Clement mlir::Value acc::ParallelOp::getNumWorkersValue() {
1058a25da1a9SValentin Clement   return getNumWorkersValue(mlir::acc::DeviceType::None);
1059a25da1a9SValentin Clement }
1060a25da1a9SValentin Clement 
1061a25da1a9SValentin Clement mlir::Value
1062a25da1a9SValentin Clement acc::ParallelOp::getNumWorkersValue(mlir::acc::DeviceType deviceType) {
1063a25da1a9SValentin Clement   return getValueInDeviceTypeSegment(getNumWorkersDeviceType(), getNumWorkers(),
1064a25da1a9SValentin Clement                                      deviceType);
1065a25da1a9SValentin Clement }
1066a25da1a9SValentin Clement 
1067a25da1a9SValentin Clement mlir::Value acc::ParallelOp::getVectorLengthValue() {
1068a25da1a9SValentin Clement   return getVectorLengthValue(mlir::acc::DeviceType::None);
1069a25da1a9SValentin Clement }
1070a25da1a9SValentin Clement 
1071a25da1a9SValentin Clement mlir::Value
1072a25da1a9SValentin Clement acc::ParallelOp::getVectorLengthValue(mlir::acc::DeviceType deviceType) {
1073a25da1a9SValentin Clement   return getValueInDeviceTypeSegment(getVectorLengthDeviceType(),
1074a25da1a9SValentin Clement                                      getVectorLength(), deviceType);
1075a25da1a9SValentin Clement }
1076a25da1a9SValentin Clement 
1077a25da1a9SValentin Clement mlir::Operation::operand_range ParallelOp::getNumGangsValues() {
1078a25da1a9SValentin Clement   return getNumGangsValues(mlir::acc::DeviceType::None);
1079a25da1a9SValentin Clement }
1080a25da1a9SValentin Clement 
1081a25da1a9SValentin Clement mlir::Operation::operand_range
1082a25da1a9SValentin Clement ParallelOp::getNumGangsValues(mlir::acc::DeviceType deviceType) {
1083a25da1a9SValentin Clement   return getValuesFromSegments(getNumGangsDeviceType(), getNumGangs(),
1084a25da1a9SValentin Clement                                getNumGangsSegments(), deviceType);
1085a25da1a9SValentin Clement }
1086a25da1a9SValentin Clement 
1087a25da1a9SValentin Clement bool acc::ParallelOp::hasWaitOnly() {
1088a25da1a9SValentin Clement   return hasWaitOnly(mlir::acc::DeviceType::None);
1089a25da1a9SValentin Clement }
1090a25da1a9SValentin Clement 
1091a25da1a9SValentin Clement bool acc::ParallelOp::hasWaitOnly(mlir::acc::DeviceType deviceType) {
1092ee6199caSValentin Clement (バレンタイン クレメン)   return hasDeviceType(getWaitOnly(), deviceType);
1093a25da1a9SValentin Clement }
1094a25da1a9SValentin Clement 
1095a25da1a9SValentin Clement mlir::Operation::operand_range ParallelOp::getWaitValues() {
1096a25da1a9SValentin Clement   return getWaitValues(mlir::acc::DeviceType::None);
1097a25da1a9SValentin Clement }
1098a25da1a9SValentin Clement 
1099a25da1a9SValentin Clement mlir::Operation::operand_range
1100a25da1a9SValentin Clement ParallelOp::getWaitValues(mlir::acc::DeviceType deviceType) {
1101c09dc2d9SValentin Clement (バレンタイン クレメン)   return getWaitValuesWithoutDevnum(
1102c09dc2d9SValentin Clement (バレンタイン クレメン)       getWaitOperandsDeviceType(), getWaitOperands(), getWaitOperandsSegments(),
1103c09dc2d9SValentin Clement (バレンタイン クレメン)       getHasWaitDevnum(), deviceType);
1104c09dc2d9SValentin Clement (バレンタイン クレメン) }
1105c09dc2d9SValentin Clement (バレンタイン クレメン) 
1106c09dc2d9SValentin Clement (バレンタイン クレメン) mlir::Value ParallelOp::getWaitDevnum() {
1107c09dc2d9SValentin Clement (バレンタイン クレメン)   return getWaitDevnum(mlir::acc::DeviceType::None);
1108c09dc2d9SValentin Clement (バレンタイン クレメン) }
1109c09dc2d9SValentin Clement (バレンタイン クレメン) 
1110c09dc2d9SValentin Clement (バレンタイン クレメン) mlir::Value ParallelOp::getWaitDevnum(mlir::acc::DeviceType deviceType) {
1111c09dc2d9SValentin Clement (バレンタイン クレメン)   return getWaitDevnumValue(getWaitOperandsDeviceType(), getWaitOperands(),
1112c09dc2d9SValentin Clement (バレンタイン クレメン)                             getWaitOperandsSegments(), getHasWaitDevnum(),
1113c09dc2d9SValentin Clement (バレンタイン クレメン)                             deviceType);
1114a25da1a9SValentin Clement }
1115a25da1a9SValentin Clement 
11168d5ba759SVijay Kandiah void ParallelOp::build(mlir::OpBuilder &odsBuilder,
11178d5ba759SVijay Kandiah                        mlir::OperationState &odsState,
11188d5ba759SVijay Kandiah                        mlir::ValueRange numGangs, mlir::ValueRange numWorkers,
11198d5ba759SVijay Kandiah                        mlir::ValueRange vectorLength,
11208d5ba759SVijay Kandiah                        mlir::ValueRange asyncOperands,
11218d5ba759SVijay Kandiah                        mlir::ValueRange waitOperands, mlir::Value ifCond,
11228d5ba759SVijay Kandiah                        mlir::Value selfCond, mlir::ValueRange reductionOperands,
11238d5ba759SVijay Kandiah                        mlir::ValueRange gangPrivateOperands,
11248d5ba759SVijay Kandiah                        mlir::ValueRange gangFirstPrivateOperands,
11258d5ba759SVijay Kandiah                        mlir::ValueRange dataClauseOperands) {
11268d5ba759SVijay Kandiah 
11278d5ba759SVijay Kandiah   ParallelOp::build(
11288d5ba759SVijay Kandiah       odsBuilder, odsState, asyncOperands, /*asyncOperandsDeviceType=*/nullptr,
11298d5ba759SVijay Kandiah       /*asyncOnly=*/nullptr, waitOperands, /*waitOperandsSegments=*/nullptr,
11308d5ba759SVijay Kandiah       /*waitOperandsDeviceType=*/nullptr, /*hasWaitDevnum=*/nullptr,
11318d5ba759SVijay Kandiah       /*waitOnly=*/nullptr, numGangs, /*numGangsSegments=*/nullptr,
11328d5ba759SVijay Kandiah       /*numGangsDeviceType=*/nullptr, numWorkers,
11338d5ba759SVijay Kandiah       /*numWorkersDeviceType=*/nullptr, vectorLength,
11348d5ba759SVijay Kandiah       /*vectorLengthDeviceType=*/nullptr, ifCond, selfCond,
11358d5ba759SVijay Kandiah       /*selfAttr=*/nullptr, reductionOperands, /*reductionRecipes=*/nullptr,
11368d5ba759SVijay Kandiah       gangPrivateOperands, /*privatizations=*/nullptr, gangFirstPrivateOperands,
11378d5ba759SVijay Kandiah       /*firstprivatizations=*/nullptr, dataClauseOperands,
11388d5ba759SVijay Kandiah       /*defaultAttr=*/nullptr, /*combined=*/nullptr);
11398d5ba759SVijay Kandiah }
11408d5ba759SVijay Kandiah 
1141a25da1a9SValentin Clement static ParseResult parseNumGangs(
1142a25da1a9SValentin Clement     mlir::OpAsmParser &parser,
1143a25da1a9SValentin Clement     llvm::SmallVectorImpl<mlir::OpAsmParser::UnresolvedOperand> &operands,
1144a25da1a9SValentin Clement     llvm::SmallVectorImpl<Type> &types, mlir::ArrayAttr &deviceTypes,
1145a25da1a9SValentin Clement     mlir::DenseI32ArrayAttr &segments) {
1146a25da1a9SValentin Clement   llvm::SmallVector<DeviceTypeAttr> attributes;
1147a25da1a9SValentin Clement   llvm::SmallVector<int32_t> seg;
1148a25da1a9SValentin Clement 
1149a25da1a9SValentin Clement   do {
1150a25da1a9SValentin Clement     if (failed(parser.parseLBrace()))
1151a25da1a9SValentin Clement       return failure();
1152a25da1a9SValentin Clement 
1153b5df6a90SValentin Clement (バレンタイン クレメン)     int32_t crtOperandsSize = operands.size();
1154a25da1a9SValentin Clement     if (failed(parser.parseCommaSeparatedList(
1155a25da1a9SValentin Clement             mlir::AsmParser::Delimiter::None, [&]() {
1156a25da1a9SValentin Clement               if (parser.parseOperand(operands.emplace_back()) ||
1157a25da1a9SValentin Clement                   parser.parseColonType(types.emplace_back()))
1158a25da1a9SValentin Clement                 return failure();
1159a25da1a9SValentin Clement               return success();
1160a25da1a9SValentin Clement             })))
1161a25da1a9SValentin Clement       return failure();
1162b5df6a90SValentin Clement (バレンタイン クレメン)     seg.push_back(operands.size() - crtOperandsSize);
1163a25da1a9SValentin Clement 
1164a25da1a9SValentin Clement     if (failed(parser.parseRBrace()))
1165a25da1a9SValentin Clement       return failure();
1166a25da1a9SValentin Clement 
1167a25da1a9SValentin Clement     if (succeeded(parser.parseOptionalLSquare())) {
1168a25da1a9SValentin Clement       if (parser.parseAttribute(attributes.emplace_back()) ||
1169a25da1a9SValentin Clement           parser.parseRSquare())
1170a25da1a9SValentin Clement         return failure();
1171a25da1a9SValentin Clement     } else {
1172a25da1a9SValentin Clement       attributes.push_back(mlir::acc::DeviceTypeAttr::get(
1173a25da1a9SValentin Clement           parser.getContext(), mlir::acc::DeviceType::None));
1174a25da1a9SValentin Clement     }
1175a25da1a9SValentin Clement   } while (succeeded(parser.parseOptionalComma()));
1176a25da1a9SValentin Clement 
1177a25da1a9SValentin Clement   llvm::SmallVector<mlir::Attribute> arrayAttr(attributes.begin(),
1178a25da1a9SValentin Clement                                                attributes.end());
1179a25da1a9SValentin Clement   deviceTypes = ArrayAttr::get(parser.getContext(), arrayAttr);
1180a25da1a9SValentin Clement   segments = DenseI32ArrayAttr::get(parser.getContext(), seg);
1181a25da1a9SValentin Clement 
1182a25da1a9SValentin Clement   return success();
1183a25da1a9SValentin Clement }
1184a25da1a9SValentin Clement 
1185bd5d41a3SValentin Clement (バレンタイン クレメン) static void printSingleDeviceType(mlir::OpAsmPrinter &p, mlir::Attribute attr) {
1186bd5d41a3SValentin Clement (バレンタイン クレメン)   auto deviceTypeAttr = mlir::dyn_cast<mlir::acc::DeviceTypeAttr>(attr);
1187bd5d41a3SValentin Clement (バレンタイン クレメン)   if (deviceTypeAttr.getValue() != mlir::acc::DeviceType::None)
1188bd5d41a3SValentin Clement (バレンタイン クレメン)     p << " [" << attr << "]";
1189bd5d41a3SValentin Clement (バレンタイン クレメン) }
1190bd5d41a3SValentin Clement (バレンタイン クレメン) 
1191a25da1a9SValentin Clement static void printNumGangs(mlir::OpAsmPrinter &p, mlir::Operation *op,
1192a25da1a9SValentin Clement                           mlir::OperandRange operands, mlir::TypeRange types,
1193a25da1a9SValentin Clement                           std::optional<mlir::ArrayAttr> deviceTypes,
1194a25da1a9SValentin Clement                           std::optional<mlir::DenseI32ArrayAttr> segments) {
1195a25da1a9SValentin Clement   unsigned opIdx = 0;
1196bd5d41a3SValentin Clement (バレンタイン クレメン)   llvm::interleaveComma(llvm::enumerate(*deviceTypes), p, [&](auto it) {
1197a25da1a9SValentin Clement     p << "{";
1198bd5d41a3SValentin Clement (バレンタイン クレメン)     llvm::interleaveComma(
1199bd5d41a3SValentin Clement (バレンタイン クレメン)         llvm::seq<int32_t>(0, (*segments)[it.index()]), p, [&](auto it) {
1200a25da1a9SValentin Clement           p << operands[opIdx] << " : " << operands[opIdx].getType();
1201a25da1a9SValentin Clement           ++opIdx;
1202bd5d41a3SValentin Clement (バレンタイン クレメン)         });
1203a25da1a9SValentin Clement     p << "}";
1204bd5d41a3SValentin Clement (バレンタイン クレメン)     printSingleDeviceType(p, it.value());
1205bd5d41a3SValentin Clement (バレンタイン クレメン)   });
1206a25da1a9SValentin Clement }
1207a25da1a9SValentin Clement 
120885939e5eSValentin Clement static ParseResult parseDeviceTypeOperandsWithSegment(
1209a25da1a9SValentin Clement     mlir::OpAsmParser &parser,
1210a25da1a9SValentin Clement     llvm::SmallVectorImpl<mlir::OpAsmParser::UnresolvedOperand> &operands,
1211a25da1a9SValentin Clement     llvm::SmallVectorImpl<Type> &types, mlir::ArrayAttr &deviceTypes,
1212a25da1a9SValentin Clement     mlir::DenseI32ArrayAttr &segments) {
1213a25da1a9SValentin Clement   llvm::SmallVector<DeviceTypeAttr> attributes;
1214a25da1a9SValentin Clement   llvm::SmallVector<int32_t> seg;
1215a25da1a9SValentin Clement 
1216a25da1a9SValentin Clement   do {
1217a25da1a9SValentin Clement     if (failed(parser.parseLBrace()))
1218a25da1a9SValentin Clement       return failure();
1219a25da1a9SValentin Clement 
1220e456689fSValentin Clement (バレンタイン クレメン)     int32_t crtOperandsSize = operands.size();
1221e456689fSValentin Clement (バレンタイン クレメン) 
1222a25da1a9SValentin Clement     if (failed(parser.parseCommaSeparatedList(
1223a25da1a9SValentin Clement             mlir::AsmParser::Delimiter::None, [&]() {
1224a25da1a9SValentin Clement               if (parser.parseOperand(operands.emplace_back()) ||
1225a25da1a9SValentin Clement                   parser.parseColonType(types.emplace_back()))
1226a25da1a9SValentin Clement                 return failure();
1227a25da1a9SValentin Clement               return success();
1228a25da1a9SValentin Clement             })))
1229a25da1a9SValentin Clement       return failure();
1230a25da1a9SValentin Clement 
1231e456689fSValentin Clement (バレンタイン クレメン)     seg.push_back(operands.size() - crtOperandsSize);
1232a25da1a9SValentin Clement 
1233a25da1a9SValentin Clement     if (failed(parser.parseRBrace()))
1234a25da1a9SValentin Clement       return failure();
1235a25da1a9SValentin Clement 
1236a25da1a9SValentin Clement     if (succeeded(parser.parseOptionalLSquare())) {
1237a25da1a9SValentin Clement       if (parser.parseAttribute(attributes.emplace_back()) ||
1238a25da1a9SValentin Clement           parser.parseRSquare())
1239a25da1a9SValentin Clement         return failure();
1240a25da1a9SValentin Clement     } else {
1241a25da1a9SValentin Clement       attributes.push_back(mlir::acc::DeviceTypeAttr::get(
1242a25da1a9SValentin Clement           parser.getContext(), mlir::acc::DeviceType::None));
1243a25da1a9SValentin Clement     }
1244a25da1a9SValentin Clement   } while (succeeded(parser.parseOptionalComma()));
1245a25da1a9SValentin Clement 
1246a25da1a9SValentin Clement   llvm::SmallVector<mlir::Attribute> arrayAttr(attributes.begin(),
1247a25da1a9SValentin Clement                                                attributes.end());
1248a25da1a9SValentin Clement   deviceTypes = ArrayAttr::get(parser.getContext(), arrayAttr);
1249a25da1a9SValentin Clement   segments = DenseI32ArrayAttr::get(parser.getContext(), seg);
1250a25da1a9SValentin Clement 
1251a25da1a9SValentin Clement   return success();
1252a25da1a9SValentin Clement }
1253a25da1a9SValentin Clement 
125485939e5eSValentin Clement static void printDeviceTypeOperandsWithSegment(
125585939e5eSValentin Clement     mlir::OpAsmPrinter &p, mlir::Operation *op, mlir::OperandRange operands,
125685939e5eSValentin Clement     mlir::TypeRange types, std::optional<mlir::ArrayAttr> deviceTypes,
1257a25da1a9SValentin Clement     std::optional<mlir::DenseI32ArrayAttr> segments) {
1258a25da1a9SValentin Clement   unsigned opIdx = 0;
1259bd5d41a3SValentin Clement (バレンタイン クレメン)   llvm::interleaveComma(llvm::enumerate(*deviceTypes), p, [&](auto it) {
1260a25da1a9SValentin Clement     p << "{";
1261bd5d41a3SValentin Clement (バレンタイン クレメン)     llvm::interleaveComma(
1262bd5d41a3SValentin Clement (バレンタイン クレメン)         llvm::seq<int32_t>(0, (*segments)[it.index()]), p, [&](auto it) {
1263a25da1a9SValentin Clement           p << operands[opIdx] << " : " << operands[opIdx].getType();
1264a25da1a9SValentin Clement           ++opIdx;
1265bd5d41a3SValentin Clement (バレンタイン クレメン)         });
1266a25da1a9SValentin Clement     p << "}";
1267bd5d41a3SValentin Clement (バレンタイン クレメン)     printSingleDeviceType(p, it.value());
1268bd5d41a3SValentin Clement (バレンタイン クレメン)   });
1269a25da1a9SValentin Clement }
1270a25da1a9SValentin Clement 
127178ef0328SValentin Clement (バレンタイン クレメン) static ParseResult parseWaitClause(
127278ef0328SValentin Clement (バレンタイン クレメン)     mlir::OpAsmParser &parser,
127378ef0328SValentin Clement (バレンタイン クレメン)     llvm::SmallVectorImpl<mlir::OpAsmParser::UnresolvedOperand> &operands,
127478ef0328SValentin Clement (バレンタイン クレメン)     llvm::SmallVectorImpl<Type> &types, mlir::ArrayAttr &deviceTypes,
1275c09dc2d9SValentin Clement (バレンタイン クレメン)     mlir::DenseI32ArrayAttr &segments, mlir::ArrayAttr &hasDevNum,
1276c09dc2d9SValentin Clement (バレンタイン クレメン)     mlir::ArrayAttr &keywordOnly) {
1277c09dc2d9SValentin Clement (バレンタイン クレメン)   llvm::SmallVector<mlir::Attribute> deviceTypeAttrs, keywordAttrs, devnum;
127878ef0328SValentin Clement (バレンタイン クレメン)   llvm::SmallVector<int32_t> seg;
127978ef0328SValentin Clement (バレンタイン クレメン) 
128078ef0328SValentin Clement (バレンタイン クレメン)   bool needCommaBeforeOperands = false;
128178ef0328SValentin Clement (バレンタイン クレメン) 
128278ef0328SValentin Clement (バレンタイン クレメン)   // Keyword only
128378ef0328SValentin Clement (バレンタイン クレメン)   if (failed(parser.parseOptionalLParen())) {
128478ef0328SValentin Clement (バレンタイン クレメン)     keywordAttrs.push_back(mlir::acc::DeviceTypeAttr::get(
128578ef0328SValentin Clement (バレンタイン クレメン)         parser.getContext(), mlir::acc::DeviceType::None));
128678ef0328SValentin Clement (バレンタイン クレメン)     keywordOnly = ArrayAttr::get(parser.getContext(), keywordAttrs);
128778ef0328SValentin Clement (バレンタイン クレメン)     return success();
128878ef0328SValentin Clement (バレンタイン クレメン)   }
128978ef0328SValentin Clement (バレンタイン クレメン) 
129078ef0328SValentin Clement (バレンタイン クレメン)   // Parse keyword only attributes
129178ef0328SValentin Clement (バレンタイン クレメン)   if (succeeded(parser.parseOptionalLSquare())) {
129278ef0328SValentin Clement (バレンタイン クレメン)     if (failed(parser.parseCommaSeparatedList([&]() {
129378ef0328SValentin Clement (バレンタイン クレメン)           if (parser.parseAttribute(keywordAttrs.emplace_back()))
129478ef0328SValentin Clement (バレンタイン クレメン)             return failure();
129578ef0328SValentin Clement (バレンタイン クレメン)           return success();
129678ef0328SValentin Clement (バレンタイン クレメン)         })))
129778ef0328SValentin Clement (バレンタイン クレメン)       return failure();
129878ef0328SValentin Clement (バレンタイン クレメン)     if (parser.parseRSquare())
129978ef0328SValentin Clement (バレンタイン クレメン)       return failure();
130078ef0328SValentin Clement (バレンタイン クレメン)     needCommaBeforeOperands = true;
130178ef0328SValentin Clement (バレンタイン クレメン)   }
130278ef0328SValentin Clement (バレンタイン クレメン) 
130378ef0328SValentin Clement (バレンタイン クレメン)   if (needCommaBeforeOperands && failed(parser.parseComma()))
130478ef0328SValentin Clement (バレンタイン クレメン)     return failure();
130578ef0328SValentin Clement (バレンタイン クレメン) 
130678ef0328SValentin Clement (バレンタイン クレメン)   do {
130778ef0328SValentin Clement (バレンタイン クレメン)     if (failed(parser.parseLBrace()))
130878ef0328SValentin Clement (バレンタイン クレメン)       return failure();
130978ef0328SValentin Clement (バレンタイン クレメン) 
131078ef0328SValentin Clement (バレンタイン クレメン)     int32_t crtOperandsSize = operands.size();
131178ef0328SValentin Clement (バレンタイン クレメン) 
1312c09dc2d9SValentin Clement (バレンタイン クレメン)     if (succeeded(parser.parseOptionalKeyword("devnum"))) {
1313c09dc2d9SValentin Clement (バレンタイン クレメン)       if (failed(parser.parseColon()))
1314c09dc2d9SValentin Clement (バレンタイン クレメン)         return failure();
1315c09dc2d9SValentin Clement (バレンタイン クレメン)       devnum.push_back(BoolAttr::get(parser.getContext(), true));
1316c09dc2d9SValentin Clement (バレンタイン クレメン)     } else {
1317c09dc2d9SValentin Clement (バレンタイン クレメン)       devnum.push_back(BoolAttr::get(parser.getContext(), false));
1318c09dc2d9SValentin Clement (バレンタイン クレメン)     }
1319c09dc2d9SValentin Clement (バレンタイン クレメン) 
132078ef0328SValentin Clement (バレンタイン クレメン)     if (failed(parser.parseCommaSeparatedList(
132178ef0328SValentin Clement (バレンタイン クレメン)             mlir::AsmParser::Delimiter::None, [&]() {
132278ef0328SValentin Clement (バレンタイン クレメン)               if (parser.parseOperand(operands.emplace_back()) ||
132378ef0328SValentin Clement (バレンタイン クレメン)                   parser.parseColonType(types.emplace_back()))
132478ef0328SValentin Clement (バレンタイン クレメン)                 return failure();
132578ef0328SValentin Clement (バレンタイン クレメン)               return success();
132678ef0328SValentin Clement (バレンタイン クレメン)             })))
132778ef0328SValentin Clement (バレンタイン クレメン)       return failure();
132878ef0328SValentin Clement (バレンタイン クレメン) 
132978ef0328SValentin Clement (バレンタイン クレメン)     seg.push_back(operands.size() - crtOperandsSize);
133078ef0328SValentin Clement (バレンタイン クレメン) 
133178ef0328SValentin Clement (バレンタイン クレメン)     if (failed(parser.parseRBrace()))
133278ef0328SValentin Clement (バレンタイン クレメン)       return failure();
133378ef0328SValentin Clement (バレンタイン クレメン) 
133478ef0328SValentin Clement (バレンタイン クレメン)     if (succeeded(parser.parseOptionalLSquare())) {
133578ef0328SValentin Clement (バレンタイン クレメン)       if (parser.parseAttribute(deviceTypeAttrs.emplace_back()) ||
133678ef0328SValentin Clement (バレンタイン クレメン)           parser.parseRSquare())
133778ef0328SValentin Clement (バレンタイン クレメン)         return failure();
133878ef0328SValentin Clement (バレンタイン クレメン)     } else {
133978ef0328SValentin Clement (バレンタイン クレメン)       deviceTypeAttrs.push_back(mlir::acc::DeviceTypeAttr::get(
134078ef0328SValentin Clement (バレンタイン クレメン)           parser.getContext(), mlir::acc::DeviceType::None));
134178ef0328SValentin Clement (バレンタイン クレメン)     }
134278ef0328SValentin Clement (バレンタイン クレメン)   } while (succeeded(parser.parseOptionalComma()));
134378ef0328SValentin Clement (バレンタイン クレメン) 
134478ef0328SValentin Clement (バレンタイン クレメン)   if (failed(parser.parseRParen()))
134578ef0328SValentin Clement (バレンタイン クレメン)     return failure();
134678ef0328SValentin Clement (バレンタイン クレメン) 
134778ef0328SValentin Clement (バレンタイン クレメン)   deviceTypes = ArrayAttr::get(parser.getContext(), deviceTypeAttrs);
134878ef0328SValentin Clement (バレンタイン クレメン)   keywordOnly = ArrayAttr::get(parser.getContext(), keywordAttrs);
134978ef0328SValentin Clement (バレンタイン クレメン)   segments = DenseI32ArrayAttr::get(parser.getContext(), seg);
1350c09dc2d9SValentin Clement (バレンタイン クレメン)   hasDevNum = ArrayAttr::get(parser.getContext(), devnum);
135178ef0328SValentin Clement (バレンタイン クレメン) 
135278ef0328SValentin Clement (バレンタイン クレメン)   return success();
135378ef0328SValentin Clement (バレンタイン クレメン) }
135478ef0328SValentin Clement (バレンタイン クレメン) 
135578ef0328SValentin Clement (バレンタイン クレメン) static bool hasOnlyDeviceTypeNone(std::optional<mlir::ArrayAttr> attrs) {
135678ef0328SValentin Clement (バレンタイン クレメン)   if (!hasDeviceTypeValues(attrs))
135778ef0328SValentin Clement (バレンタイン クレメン)     return false;
135878ef0328SValentin Clement (バレンタイン クレメン)   if (attrs->size() != 1)
135978ef0328SValentin Clement (バレンタイン クレメン)     return false;
136078ef0328SValentin Clement (バレンタイン クレメン)   if (auto deviceTypeAttr =
136178ef0328SValentin Clement (バレンタイン クレメン)           mlir::dyn_cast<mlir::acc::DeviceTypeAttr>((*attrs)[0]))
136278ef0328SValentin Clement (バレンタイン クレメン)     return deviceTypeAttr.getValue() == mlir::acc::DeviceType::None;
136378ef0328SValentin Clement (バレンタイン クレメン)   return false;
136478ef0328SValentin Clement (バレンタイン クレメン) }
136578ef0328SValentin Clement (バレンタイン クレメン) 
136678ef0328SValentin Clement (バレンタイン クレメン) static void printWaitClause(mlir::OpAsmPrinter &p, mlir::Operation *op,
136778ef0328SValentin Clement (バレンタイン クレメン)                             mlir::OperandRange operands, mlir::TypeRange types,
136878ef0328SValentin Clement (バレンタイン クレメン)                             std::optional<mlir::ArrayAttr> deviceTypes,
136978ef0328SValentin Clement (バレンタイン クレメン)                             std::optional<mlir::DenseI32ArrayAttr> segments,
1370c09dc2d9SValentin Clement (バレンタイン クレメン)                             std::optional<mlir::ArrayAttr> hasDevNum,
137178ef0328SValentin Clement (バレンタイン クレメン)                             std::optional<mlir::ArrayAttr> keywordOnly) {
137278ef0328SValentin Clement (バレンタイン クレメン) 
137378ef0328SValentin Clement (バレンタイン クレメン)   if (operands.begin() == operands.end() && hasOnlyDeviceTypeNone(keywordOnly))
137478ef0328SValentin Clement (バレンタイン クレメン)     return;
137578ef0328SValentin Clement (バレンタイン クレメン) 
137678ef0328SValentin Clement (バレンタイン クレメン)   p << "(";
137778ef0328SValentin Clement (バレンタイン クレメン) 
137878ef0328SValentin Clement (バレンタイン クレメン)   printDeviceTypes(p, keywordOnly);
137978ef0328SValentin Clement (バレンタイン クレメン)   if (hasDeviceTypeValues(keywordOnly) && hasDeviceTypeValues(deviceTypes))
138078ef0328SValentin Clement (バレンタイン クレメン)     p << ", ";
138178ef0328SValentin Clement (バレンタイン クレメン) 
138278ef0328SValentin Clement (バレンタイン クレメン)   unsigned opIdx = 0;
138378ef0328SValentin Clement (バレンタイン クレメン)   llvm::interleaveComma(llvm::enumerate(*deviceTypes), p, [&](auto it) {
138478ef0328SValentin Clement (バレンタイン クレメン)     p << "{";
1385c09dc2d9SValentin Clement (バレンタイン クレメン)     auto boolAttr = mlir::dyn_cast<mlir::BoolAttr>((*hasDevNum)[it.index()]);
1386c09dc2d9SValentin Clement (バレンタイン クレメン)     if (boolAttr && boolAttr.getValue())
1387c09dc2d9SValentin Clement (バレンタイン クレメン)       p << "devnum: ";
138878ef0328SValentin Clement (バレンタイン クレメン)     llvm::interleaveComma(
138978ef0328SValentin Clement (バレンタイン クレメン)         llvm::seq<int32_t>(0, (*segments)[it.index()]), p, [&](auto it) {
139078ef0328SValentin Clement (バレンタイン クレメン)           p << operands[opIdx] << " : " << operands[opIdx].getType();
139178ef0328SValentin Clement (バレンタイン クレメン)           ++opIdx;
139278ef0328SValentin Clement (バレンタイン クレメン)         });
139378ef0328SValentin Clement (バレンタイン クレメン)     p << "}";
139478ef0328SValentin Clement (バレンタイン クレメン)     printSingleDeviceType(p, it.value());
139578ef0328SValentin Clement (バレンタイン クレメン)   });
139678ef0328SValentin Clement (バレンタイン クレメン) 
139778ef0328SValentin Clement (バレンタイン クレメン)   p << ")";
139878ef0328SValentin Clement (バレンタイン クレメン) }
139978ef0328SValentin Clement (バレンタイン クレメン) 
1400a25da1a9SValentin Clement static ParseResult parseDeviceTypeOperands(
1401a25da1a9SValentin Clement     mlir::OpAsmParser &parser,
1402a25da1a9SValentin Clement     llvm::SmallVectorImpl<mlir::OpAsmParser::UnresolvedOperand> &operands,
1403a25da1a9SValentin Clement     llvm::SmallVectorImpl<Type> &types, mlir::ArrayAttr &deviceTypes) {
1404a25da1a9SValentin Clement   llvm::SmallVector<DeviceTypeAttr> attributes;
1405a25da1a9SValentin Clement   if (failed(parser.parseCommaSeparatedList([&]() {
1406a25da1a9SValentin Clement         if (parser.parseOperand(operands.emplace_back()) ||
1407a25da1a9SValentin Clement             parser.parseColonType(types.emplace_back()))
1408a25da1a9SValentin Clement           return failure();
1409a25da1a9SValentin Clement         if (succeeded(parser.parseOptionalLSquare())) {
1410a25da1a9SValentin Clement           if (parser.parseAttribute(attributes.emplace_back()) ||
1411a25da1a9SValentin Clement               parser.parseRSquare())
1412a25da1a9SValentin Clement             return failure();
1413a25da1a9SValentin Clement         } else {
1414a25da1a9SValentin Clement           attributes.push_back(mlir::acc::DeviceTypeAttr::get(
1415a25da1a9SValentin Clement               parser.getContext(), mlir::acc::DeviceType::None));
1416a25da1a9SValentin Clement         }
1417a25da1a9SValentin Clement         return success();
1418a25da1a9SValentin Clement       })))
1419a25da1a9SValentin Clement     return failure();
1420a25da1a9SValentin Clement   llvm::SmallVector<mlir::Attribute> arrayAttr(attributes.begin(),
1421a25da1a9SValentin Clement                                                attributes.end());
1422a25da1a9SValentin Clement   deviceTypes = ArrayAttr::get(parser.getContext(), arrayAttr);
1423a25da1a9SValentin Clement   return success();
1424a25da1a9SValentin Clement }
1425a25da1a9SValentin Clement 
1426a25da1a9SValentin Clement static void
1427a25da1a9SValentin Clement printDeviceTypeOperands(mlir::OpAsmPrinter &p, mlir::Operation *op,
1428a25da1a9SValentin Clement                         mlir::OperandRange operands, mlir::TypeRange types,
1429a25da1a9SValentin Clement                         std::optional<mlir::ArrayAttr> deviceTypes) {
143078ef0328SValentin Clement (バレンタイン クレメン)   if (!hasDeviceTypeValues(deviceTypes))
143178ef0328SValentin Clement (バレンタイン クレメン)     return;
1432bd5d41a3SValentin Clement (バレンタイン クレメン)   llvm::interleaveComma(llvm::zip(*deviceTypes, operands), p, [&](auto it) {
1433bd5d41a3SValentin Clement (バレンタイン クレメン)     p << std::get<1>(it) << " : " << std::get<1>(it).getType();
1434bd5d41a3SValentin Clement (バレンタイン クレメン)     printSingleDeviceType(p, std::get<0>(it));
1435bd5d41a3SValentin Clement (バレンタイン クレメン)   });
143640f5f905SValentin Clement (バレンタイン クレメン) }
143740f5f905SValentin Clement (バレンタイン クレメン) 
143840f5f905SValentin Clement (バレンタイン クレメン) static ParseResult parseDeviceTypeOperandsWithKeywordOnly(
143940f5f905SValentin Clement (バレンタイン クレメン)     mlir::OpAsmParser &parser,
144040f5f905SValentin Clement (バレンタイン クレメン)     llvm::SmallVectorImpl<mlir::OpAsmParser::UnresolvedOperand> &operands,
144140f5f905SValentin Clement (バレンタイン クレメン)     llvm::SmallVectorImpl<Type> &types, mlir::ArrayAttr &deviceTypes,
144240f5f905SValentin Clement (バレンタイン クレメン)     mlir::ArrayAttr &keywordOnlyDeviceType) {
144340f5f905SValentin Clement (バレンタイン クレメン) 
144440f5f905SValentin Clement (バレンタイン クレメン)   llvm::SmallVector<mlir::Attribute> keywordOnlyDeviceTypeAttributes;
144540f5f905SValentin Clement (バレンタイン クレメン)   bool needCommaBeforeOperands = false;
144640f5f905SValentin Clement (バレンタイン クレメン) 
14476b42625bSValentin Clement (バレンタイン クレメン)   if (failed(parser.parseOptionalLParen())) {
14486b42625bSValentin Clement (バレンタイン クレメン)     // Keyword only
14496b42625bSValentin Clement (バレンタイン クレメン)     keywordOnlyDeviceTypeAttributes.push_back(mlir::acc::DeviceTypeAttr::get(
14506b42625bSValentin Clement (バレンタイン クレメン)         parser.getContext(), mlir::acc::DeviceType::None));
14516b42625bSValentin Clement (バレンタイン クレメン)     keywordOnlyDeviceType =
14526b42625bSValentin Clement (バレンタイン クレメン)         ArrayAttr::get(parser.getContext(), keywordOnlyDeviceTypeAttributes);
14536b42625bSValentin Clement (バレンタイン クレメン)     return success();
14546b42625bSValentin Clement (バレンタイン クレメン)   }
145540f5f905SValentin Clement (バレンタイン クレメン) 
145640f5f905SValentin Clement (バレンタイン クレメン)   // Parse keyword only attributes
145740f5f905SValentin Clement (バレンタイン クレメン)   if (succeeded(parser.parseOptionalLSquare())) {
14583eb4178bSValentin Clement (バレンタイン クレメン)     // Parse keyword only attributes
145940f5f905SValentin Clement (バレンタイン クレメン)     if (failed(parser.parseCommaSeparatedList([&]() {
146040f5f905SValentin Clement (バレンタイン クレメン)           if (parser.parseAttribute(
146140f5f905SValentin Clement (バレンタイン クレメン)                   keywordOnlyDeviceTypeAttributes.emplace_back()))
146240f5f905SValentin Clement (バレンタイン クレメン)             return failure();
146340f5f905SValentin Clement (バレンタイン クレメン)           return success();
146440f5f905SValentin Clement (バレンタイン クレメン)         })))
146540f5f905SValentin Clement (バレンタイン クレメン)       return failure();
146640f5f905SValentin Clement (バレンタイン クレメン)     if (parser.parseRSquare())
146740f5f905SValentin Clement (バレンタイン クレメン)       return failure();
146840f5f905SValentin Clement (バレンタイン クレメン)     needCommaBeforeOperands = true;
146940f5f905SValentin Clement (バレンタイン クレメン)   }
147040f5f905SValentin Clement (バレンタイン クレメン) 
147140f5f905SValentin Clement (バレンタイン クレメン)   if (needCommaBeforeOperands && failed(parser.parseComma()))
147240f5f905SValentin Clement (バレンタイン クレメン)     return failure();
147340f5f905SValentin Clement (バレンタイン クレメン) 
147440f5f905SValentin Clement (バレンタイン クレメン)   llvm::SmallVector<DeviceTypeAttr> attributes;
147540f5f905SValentin Clement (バレンタイン クレメン)   if (failed(parser.parseCommaSeparatedList([&]() {
147640f5f905SValentin Clement (バレンタイン クレメン)         if (parser.parseOperand(operands.emplace_back()) ||
147740f5f905SValentin Clement (バレンタイン クレメン)             parser.parseColonType(types.emplace_back()))
147840f5f905SValentin Clement (バレンタイン クレメン)           return failure();
147940f5f905SValentin Clement (バレンタイン クレメン)         if (succeeded(parser.parseOptionalLSquare())) {
148040f5f905SValentin Clement (バレンタイン クレメン)           if (parser.parseAttribute(attributes.emplace_back()) ||
148140f5f905SValentin Clement (バレンタイン クレメン)               parser.parseRSquare())
148240f5f905SValentin Clement (バレンタイン クレメン)             return failure();
148340f5f905SValentin Clement (バレンタイン クレメン)         } else {
148440f5f905SValentin Clement (バレンタイン クレメン)           attributes.push_back(mlir::acc::DeviceTypeAttr::get(
148540f5f905SValentin Clement (バレンタイン クレメン)               parser.getContext(), mlir::acc::DeviceType::None));
148640f5f905SValentin Clement (バレンタイン クレメン)         }
148740f5f905SValentin Clement (バレンタイン クレメン)         return success();
148840f5f905SValentin Clement (バレンタイン クレメン)       })))
148940f5f905SValentin Clement (バレンタイン クレメン)     return failure();
149040f5f905SValentin Clement (バレンタイン クレメン) 
149140f5f905SValentin Clement (バレンタイン クレメン)   if (failed(parser.parseRParen()))
149240f5f905SValentin Clement (バレンタイン クレメン)     return failure();
149340f5f905SValentin Clement (バレンタイン クレメン) 
149440f5f905SValentin Clement (バレンタイン クレメン)   llvm::SmallVector<mlir::Attribute> arrayAttr(attributes.begin(),
149540f5f905SValentin Clement (バレンタイン クレメン)                                                attributes.end());
149640f5f905SValentin Clement (バレンタイン クレメン)   deviceTypes = ArrayAttr::get(parser.getContext(), arrayAttr);
149740f5f905SValentin Clement (バレンタイン クレメン)   return success();
149840f5f905SValentin Clement (バレンタイン クレメン) }
149940f5f905SValentin Clement (バレンタイン クレメン) 
150040f5f905SValentin Clement (バレンタイン クレメン) static void printDeviceTypeOperandsWithKeywordOnly(
150140f5f905SValentin Clement (バレンタイン クレメン)     mlir::OpAsmPrinter &p, mlir::Operation *op, mlir::OperandRange operands,
150240f5f905SValentin Clement (バレンタイン クレメン)     mlir::TypeRange types, std::optional<mlir::ArrayAttr> deviceTypes,
150340f5f905SValentin Clement (バレンタイン クレメン)     std::optional<mlir::ArrayAttr> keywordOnlyDeviceTypes) {
150440f5f905SValentin Clement (バレンタイン クレメン) 
150578ef0328SValentin Clement (バレンタイン クレメン)   if (operands.begin() == operands.end() &&
150678ef0328SValentin Clement (バレンタイン クレメン)       hasOnlyDeviceTypeNone(keywordOnlyDeviceTypes)) {
150740f5f905SValentin Clement (バレンタイン クレメン)     return;
150840f5f905SValentin Clement (バレンタイン クレメン)   }
150940f5f905SValentin Clement (バレンタイン クレメン) 
15106b42625bSValentin Clement (バレンタイン クレメン)   p << "(";
151140f5f905SValentin Clement (バレンタイン クレメン)   printDeviceTypes(p, keywordOnlyDeviceTypes);
151240f5f905SValentin Clement (バレンタイン クレメン)   if (hasDeviceTypeValues(keywordOnlyDeviceTypes) &&
151340f5f905SValentin Clement (バレンタイン クレメン)       hasDeviceTypeValues(deviceTypes))
151440f5f905SValentin Clement (バレンタイン クレメン)     p << ", ";
1515bd5d41a3SValentin Clement (バレンタイン クレメン)   printDeviceTypeOperands(p, op, operands, types, deviceTypes);
151640f5f905SValentin Clement (バレンタイン クレメン)   p << ")";
1517a25da1a9SValentin Clement }
1518a25da1a9SValentin Clement 
1519a435e1f6SRazvan Lupusoru static ParseResult
1520a435e1f6SRazvan Lupusoru parseCombinedConstructsLoop(mlir::OpAsmParser &parser,
1521a435e1f6SRazvan Lupusoru                             mlir::acc::CombinedConstructsTypeAttr &attr) {
1522a435e1f6SRazvan Lupusoru   if (succeeded(parser.parseOptionalKeyword("combined"))) {
1523a435e1f6SRazvan Lupusoru     if (parser.parseLParen())
1524a435e1f6SRazvan Lupusoru       return failure();
1525a435e1f6SRazvan Lupusoru     if (succeeded(parser.parseOptionalKeyword("kernels"))) {
1526a435e1f6SRazvan Lupusoru       attr = mlir::acc::CombinedConstructsTypeAttr::get(
1527a435e1f6SRazvan Lupusoru           parser.getContext(), mlir::acc::CombinedConstructsType::KernelsLoop);
1528a435e1f6SRazvan Lupusoru     } else if (succeeded(parser.parseOptionalKeyword("parallel"))) {
1529a435e1f6SRazvan Lupusoru       attr = mlir::acc::CombinedConstructsTypeAttr::get(
1530a435e1f6SRazvan Lupusoru           parser.getContext(), mlir::acc::CombinedConstructsType::ParallelLoop);
1531a435e1f6SRazvan Lupusoru     } else if (succeeded(parser.parseOptionalKeyword("serial"))) {
1532a435e1f6SRazvan Lupusoru       attr = mlir::acc::CombinedConstructsTypeAttr::get(
1533a435e1f6SRazvan Lupusoru           parser.getContext(), mlir::acc::CombinedConstructsType::SerialLoop);
1534a435e1f6SRazvan Lupusoru     } else {
1535a435e1f6SRazvan Lupusoru       parser.emitError(parser.getCurrentLocation(),
1536a435e1f6SRazvan Lupusoru                        "expected compute construct name");
1537a435e1f6SRazvan Lupusoru       return failure();
1538a435e1f6SRazvan Lupusoru     }
1539a435e1f6SRazvan Lupusoru     if (parser.parseRParen())
1540a435e1f6SRazvan Lupusoru       return failure();
1541a435e1f6SRazvan Lupusoru   }
1542a435e1f6SRazvan Lupusoru   return success();
1543a435e1f6SRazvan Lupusoru }
1544a435e1f6SRazvan Lupusoru 
1545a435e1f6SRazvan Lupusoru static void
1546a435e1f6SRazvan Lupusoru printCombinedConstructsLoop(mlir::OpAsmPrinter &p, mlir::Operation *op,
1547a435e1f6SRazvan Lupusoru                             mlir::acc::CombinedConstructsTypeAttr attr) {
1548a435e1f6SRazvan Lupusoru   if (attr) {
1549a435e1f6SRazvan Lupusoru     switch (attr.getValue()) {
1550a435e1f6SRazvan Lupusoru     case mlir::acc::CombinedConstructsType::KernelsLoop:
1551a435e1f6SRazvan Lupusoru       p << "combined(kernels)";
1552a435e1f6SRazvan Lupusoru       break;
1553a435e1f6SRazvan Lupusoru     case mlir::acc::CombinedConstructsType::ParallelLoop:
1554a435e1f6SRazvan Lupusoru       p << "combined(parallel)";
1555a435e1f6SRazvan Lupusoru       break;
1556a435e1f6SRazvan Lupusoru     case mlir::acc::CombinedConstructsType::SerialLoop:
1557a435e1f6SRazvan Lupusoru       p << "combined(serial)";
1558a435e1f6SRazvan Lupusoru       break;
1559a435e1f6SRazvan Lupusoru     };
1560a435e1f6SRazvan Lupusoru   }
1561a435e1f6SRazvan Lupusoru }
1562a435e1f6SRazvan Lupusoru 
15634225e7faSValentin Clement //===----------------------------------------------------------------------===//
1564f8330c14SValentin Clement // SerialOp
1565f8330c14SValentin Clement //===----------------------------------------------------------------------===//
1566f8330c14SValentin Clement 
1567f8330c14SValentin Clement unsigned SerialOp::getNumDataOperands() {
1568c0a15970SRazvan Lupusoru   return getReductionOperands().size() + getPrivateOperands().size() +
1569c0a15970SRazvan Lupusoru          getFirstprivateOperands().size() + getDataClauseOperands().size();
1570f8330c14SValentin Clement }
1571f8330c14SValentin Clement 
1572f8330c14SValentin Clement Value SerialOp::getDataOperand(unsigned i) {
1573c09dc2d9SValentin Clement (バレンタイン クレメン)   unsigned numOptional = getAsyncOperands().size();
1574f8330c14SValentin Clement   numOptional += getIfCond() ? 1 : 0;
1575f8330c14SValentin Clement   numOptional += getSelfCond() ? 1 : 0;
1576f8330c14SValentin Clement   return getOperand(getWaitOperands().size() + numOptional + i);
1577f8330c14SValentin Clement }
1578f8330c14SValentin Clement 
1579a25da1a9SValentin Clement bool acc::SerialOp::hasAsyncOnly() {
1580a25da1a9SValentin Clement   return hasAsyncOnly(mlir::acc::DeviceType::None);
1581a25da1a9SValentin Clement }
1582a25da1a9SValentin Clement 
1583a25da1a9SValentin Clement bool acc::SerialOp::hasAsyncOnly(mlir::acc::DeviceType deviceType) {
1584ee6199caSValentin Clement (バレンタイン クレメン)   return hasDeviceType(getAsyncOnly(), deviceType);
1585a25da1a9SValentin Clement }
1586a25da1a9SValentin Clement 
1587a25da1a9SValentin Clement mlir::Value acc::SerialOp::getAsyncValue() {
1588a25da1a9SValentin Clement   return getAsyncValue(mlir::acc::DeviceType::None);
1589a25da1a9SValentin Clement }
1590a25da1a9SValentin Clement 
1591a25da1a9SValentin Clement mlir::Value acc::SerialOp::getAsyncValue(mlir::acc::DeviceType deviceType) {
1592c09dc2d9SValentin Clement (バレンタイン クレメン)   return getValueInDeviceTypeSegment(getAsyncOperandsDeviceType(),
1593c09dc2d9SValentin Clement (バレンタイン クレメン)                                      getAsyncOperands(), deviceType);
1594a25da1a9SValentin Clement }
1595a25da1a9SValentin Clement 
1596a25da1a9SValentin Clement bool acc::SerialOp::hasWaitOnly() {
1597a25da1a9SValentin Clement   return hasWaitOnly(mlir::acc::DeviceType::None);
1598a25da1a9SValentin Clement }
1599a25da1a9SValentin Clement 
1600a25da1a9SValentin Clement bool acc::SerialOp::hasWaitOnly(mlir::acc::DeviceType deviceType) {
1601ee6199caSValentin Clement (バレンタイン クレメン)   return hasDeviceType(getWaitOnly(), deviceType);
1602a25da1a9SValentin Clement }
1603a25da1a9SValentin Clement 
1604a25da1a9SValentin Clement mlir::Operation::operand_range SerialOp::getWaitValues() {
1605a25da1a9SValentin Clement   return getWaitValues(mlir::acc::DeviceType::None);
1606a25da1a9SValentin Clement }
1607a25da1a9SValentin Clement 
1608a25da1a9SValentin Clement mlir::Operation::operand_range
1609a25da1a9SValentin Clement SerialOp::getWaitValues(mlir::acc::DeviceType deviceType) {
1610c09dc2d9SValentin Clement (バレンタイン クレメン)   return getWaitValuesWithoutDevnum(
1611c09dc2d9SValentin Clement (バレンタイン クレメン)       getWaitOperandsDeviceType(), getWaitOperands(), getWaitOperandsSegments(),
1612c09dc2d9SValentin Clement (バレンタイン クレメン)       getHasWaitDevnum(), deviceType);
1613c09dc2d9SValentin Clement (バレンタイン クレメン) }
1614c09dc2d9SValentin Clement (バレンタイン クレメン) 
1615c09dc2d9SValentin Clement (バレンタイン クレメン) mlir::Value SerialOp::getWaitDevnum() {
1616c09dc2d9SValentin Clement (バレンタイン クレメン)   return getWaitDevnum(mlir::acc::DeviceType::None);
1617c09dc2d9SValentin Clement (バレンタイン クレメン) }
1618c09dc2d9SValentin Clement (バレンタイン クレメン) 
1619c09dc2d9SValentin Clement (バレンタイン クレメン) mlir::Value SerialOp::getWaitDevnum(mlir::acc::DeviceType deviceType) {
1620c09dc2d9SValentin Clement (バレンタイン クレメン)   return getWaitDevnumValue(getWaitOperandsDeviceType(), getWaitOperands(),
1621c09dc2d9SValentin Clement (バレンタイン クレメン)                             getWaitOperandsSegments(), getHasWaitDevnum(),
1622c09dc2d9SValentin Clement (バレンタイン クレメン)                             deviceType);
1623a25da1a9SValentin Clement }
1624a25da1a9SValentin Clement 
1625aad53e3bSValentin Clement LogicalResult acc::SerialOp::verify() {
1626eaf29b32SValentin Clement   if (failed(checkSymOperandList<mlir::acc::PrivateRecipeOp>(
1627c0a15970SRazvan Lupusoru           *this, getPrivatizations(), getPrivateOperands(), "private",
162826b2b5a5SValentin Clement (バレンタイン クレメン)           "privatizations", /*checkOperandType=*/false)))
1629eaf29b32SValentin Clement     return failure();
1630c0a15970SRazvan Lupusoru   if (failed(checkSymOperandList<mlir::acc::FirstprivateRecipeOp>(
1631c0a15970SRazvan Lupusoru           *this, getFirstprivatizations(), getFirstprivateOperands(),
1632c0a15970SRazvan Lupusoru           "firstprivate", "firstprivatizations", /*checkOperandType=*/false)))
1633c0a15970SRazvan Lupusoru     return failure();
163474f15d9cSValentin Clement   if (failed(checkSymOperandList<mlir::acc::ReductionRecipeOp>(
163574f15d9cSValentin Clement           *this, getReductionRecipes(), getReductionOperands(), "reduction",
16365e3faa05SRazvan Lupusoru           "reductions", false)))
163774f15d9cSValentin Clement     return failure();
1638a25da1a9SValentin Clement 
1639a25da1a9SValentin Clement   if (failed(verifyDeviceTypeAndSegmentCountMatch(
1640a25da1a9SValentin Clement           *this, getWaitOperands(), getWaitOperandsSegmentsAttr(),
1641a25da1a9SValentin Clement           getWaitOperandsDeviceTypeAttr(), "wait")))
1642a25da1a9SValentin Clement     return failure();
1643a25da1a9SValentin Clement 
1644c09dc2d9SValentin Clement (バレンタイン クレメン)   if (failed(verifyDeviceTypeCountMatch(*this, getAsyncOperands(),
1645c09dc2d9SValentin Clement (バレンタイン クレメン)                                         getAsyncOperandsDeviceTypeAttr(),
1646c09dc2d9SValentin Clement (バレンタイン クレメン)                                         "async")))
1647c09dc2d9SValentin Clement (バレンタイン クレメン)     return failure();
1648c09dc2d9SValentin Clement (バレンタイン クレメン) 
1649c09dc2d9SValentin Clement (バレンタイン クレメン)   if (failed(checkWaitAndAsyncConflict<acc::SerialOp>(*this)))
1650a25da1a9SValentin Clement     return failure();
1651a25da1a9SValentin Clement 
1652aad53e3bSValentin Clement   return checkDataOperands<acc::SerialOp>(*this, getDataClauseOperands());
1653aad53e3bSValentin Clement }
1654aad53e3bSValentin Clement 
1655f8330c14SValentin Clement //===----------------------------------------------------------------------===//
1656d56b74eaSValentin Clement // KernelsOp
1657d56b74eaSValentin Clement //===----------------------------------------------------------------------===//
1658d56b74eaSValentin Clement 
1659d56b74eaSValentin Clement unsigned KernelsOp::getNumDataOperands() {
16601e463942SValentin Clement   return getDataClauseOperands().size();
1661d56b74eaSValentin Clement }
1662d56b74eaSValentin Clement 
1663d56b74eaSValentin Clement Value KernelsOp::getDataOperand(unsigned i) {
1664c09dc2d9SValentin Clement (バレンタイン クレメン)   unsigned numOptional = getAsyncOperands().size();
1665c4a63b8eSValentin Clement   numOptional += getWaitOperands().size();
1666c4a63b8eSValentin Clement   numOptional += getNumGangs().size();
1667a25da1a9SValentin Clement   numOptional += getNumWorkers().size();
1668a25da1a9SValentin Clement   numOptional += getVectorLength().size();
1669d56b74eaSValentin Clement   numOptional += getIfCond() ? 1 : 0;
1670d56b74eaSValentin Clement   numOptional += getSelfCond() ? 1 : 0;
1671c4a63b8eSValentin Clement   return getOperand(numOptional + i);
1672d56b74eaSValentin Clement }
1673d56b74eaSValentin Clement 
1674a25da1a9SValentin Clement bool acc::KernelsOp::hasAsyncOnly() {
1675a25da1a9SValentin Clement   return hasAsyncOnly(mlir::acc::DeviceType::None);
1676a25da1a9SValentin Clement }
1677a25da1a9SValentin Clement 
1678a25da1a9SValentin Clement bool acc::KernelsOp::hasAsyncOnly(mlir::acc::DeviceType deviceType) {
1679ee6199caSValentin Clement (バレンタイン クレメン)   return hasDeviceType(getAsyncOnly(), deviceType);
1680a25da1a9SValentin Clement }
1681a25da1a9SValentin Clement 
1682a25da1a9SValentin Clement mlir::Value acc::KernelsOp::getAsyncValue() {
1683a25da1a9SValentin Clement   return getAsyncValue(mlir::acc::DeviceType::None);
1684a25da1a9SValentin Clement }
1685a25da1a9SValentin Clement 
1686a25da1a9SValentin Clement mlir::Value acc::KernelsOp::getAsyncValue(mlir::acc::DeviceType deviceType) {
1687c09dc2d9SValentin Clement (バレンタイン クレメン)   return getValueInDeviceTypeSegment(getAsyncOperandsDeviceType(),
1688c09dc2d9SValentin Clement (バレンタイン クレメン)                                      getAsyncOperands(), deviceType);
1689a25da1a9SValentin Clement }
1690a25da1a9SValentin Clement 
1691a25da1a9SValentin Clement mlir::Value acc::KernelsOp::getNumWorkersValue() {
1692a25da1a9SValentin Clement   return getNumWorkersValue(mlir::acc::DeviceType::None);
1693a25da1a9SValentin Clement }
1694a25da1a9SValentin Clement 
1695a25da1a9SValentin Clement mlir::Value
1696a25da1a9SValentin Clement acc::KernelsOp::getNumWorkersValue(mlir::acc::DeviceType deviceType) {
1697a25da1a9SValentin Clement   return getValueInDeviceTypeSegment(getNumWorkersDeviceType(), getNumWorkers(),
1698a25da1a9SValentin Clement                                      deviceType);
1699a25da1a9SValentin Clement }
1700a25da1a9SValentin Clement 
1701a25da1a9SValentin Clement mlir::Value acc::KernelsOp::getVectorLengthValue() {
1702a25da1a9SValentin Clement   return getVectorLengthValue(mlir::acc::DeviceType::None);
1703a25da1a9SValentin Clement }
1704a25da1a9SValentin Clement 
1705a25da1a9SValentin Clement mlir::Value
1706a25da1a9SValentin Clement acc::KernelsOp::getVectorLengthValue(mlir::acc::DeviceType deviceType) {
1707a25da1a9SValentin Clement   return getValueInDeviceTypeSegment(getVectorLengthDeviceType(),
1708a25da1a9SValentin Clement                                      getVectorLength(), deviceType);
1709a25da1a9SValentin Clement }
1710a25da1a9SValentin Clement 
1711a25da1a9SValentin Clement mlir::Operation::operand_range KernelsOp::getNumGangsValues() {
1712a25da1a9SValentin Clement   return getNumGangsValues(mlir::acc::DeviceType::None);
1713a25da1a9SValentin Clement }
1714a25da1a9SValentin Clement 
1715a25da1a9SValentin Clement mlir::Operation::operand_range
1716a25da1a9SValentin Clement KernelsOp::getNumGangsValues(mlir::acc::DeviceType deviceType) {
1717a25da1a9SValentin Clement   return getValuesFromSegments(getNumGangsDeviceType(), getNumGangs(),
1718a25da1a9SValentin Clement                                getNumGangsSegments(), deviceType);
1719a25da1a9SValentin Clement }
1720a25da1a9SValentin Clement 
1721a25da1a9SValentin Clement bool acc::KernelsOp::hasWaitOnly() {
1722a25da1a9SValentin Clement   return hasWaitOnly(mlir::acc::DeviceType::None);
1723a25da1a9SValentin Clement }
1724a25da1a9SValentin Clement 
1725a25da1a9SValentin Clement bool acc::KernelsOp::hasWaitOnly(mlir::acc::DeviceType deviceType) {
1726ee6199caSValentin Clement (バレンタイン クレメン)   return hasDeviceType(getWaitOnly(), deviceType);
1727a25da1a9SValentin Clement }
1728a25da1a9SValentin Clement 
1729a25da1a9SValentin Clement mlir::Operation::operand_range KernelsOp::getWaitValues() {
1730a25da1a9SValentin Clement   return getWaitValues(mlir::acc::DeviceType::None);
1731a25da1a9SValentin Clement }
1732a25da1a9SValentin Clement 
1733a25da1a9SValentin Clement mlir::Operation::operand_range
1734a25da1a9SValentin Clement KernelsOp::getWaitValues(mlir::acc::DeviceType deviceType) {
1735c09dc2d9SValentin Clement (バレンタイン クレメン)   return getWaitValuesWithoutDevnum(
1736c09dc2d9SValentin Clement (バレンタイン クレメン)       getWaitOperandsDeviceType(), getWaitOperands(), getWaitOperandsSegments(),
1737c09dc2d9SValentin Clement (バレンタイン クレメン)       getHasWaitDevnum(), deviceType);
1738c09dc2d9SValentin Clement (バレンタイン クレメン) }
1739c09dc2d9SValentin Clement (バレンタイン クレメン) 
1740c09dc2d9SValentin Clement (バレンタイン クレメン) mlir::Value KernelsOp::getWaitDevnum() {
1741c09dc2d9SValentin Clement (バレンタイン クレメン)   return getWaitDevnum(mlir::acc::DeviceType::None);
1742c09dc2d9SValentin Clement (バレンタイン クレメン) }
1743c09dc2d9SValentin Clement (バレンタイン クレメン) 
1744c09dc2d9SValentin Clement (バレンタイン クレメン) mlir::Value KernelsOp::getWaitDevnum(mlir::acc::DeviceType deviceType) {
1745c09dc2d9SValentin Clement (バレンタイン クレメン)   return getWaitDevnumValue(getWaitOperandsDeviceType(), getWaitOperands(),
1746c09dc2d9SValentin Clement (バレンタイン クレメン)                             getWaitOperandsSegments(), getHasWaitDevnum(),
1747c09dc2d9SValentin Clement (バレンタイン クレメン)                             deviceType);
1748a25da1a9SValentin Clement }
1749a25da1a9SValentin Clement 
1750aad53e3bSValentin Clement LogicalResult acc::KernelsOp::verify() {
1751a25da1a9SValentin Clement   if (failed(verifyDeviceTypeAndSegmentCountMatch(
1752a25da1a9SValentin Clement           *this, getNumGangs(), getNumGangsSegmentsAttr(),
1753a25da1a9SValentin Clement           getNumGangsDeviceTypeAttr(), "num_gangs", 3)))
1754a25da1a9SValentin Clement     return failure();
1755a25da1a9SValentin Clement 
1756a25da1a9SValentin Clement   if (failed(verifyDeviceTypeAndSegmentCountMatch(
1757a25da1a9SValentin Clement           *this, getWaitOperands(), getWaitOperandsSegmentsAttr(),
1758a25da1a9SValentin Clement           getWaitOperandsDeviceTypeAttr(), "wait")))
1759a25da1a9SValentin Clement     return failure();
1760a25da1a9SValentin Clement 
1761a25da1a9SValentin Clement   if (failed(verifyDeviceTypeCountMatch(*this, getNumWorkers(),
1762a25da1a9SValentin Clement                                         getNumWorkersDeviceTypeAttr(),
1763a25da1a9SValentin Clement                                         "num_workers")))
1764a25da1a9SValentin Clement     return failure();
1765a25da1a9SValentin Clement 
1766a25da1a9SValentin Clement   if (failed(verifyDeviceTypeCountMatch(*this, getVectorLength(),
1767a25da1a9SValentin Clement                                         getVectorLengthDeviceTypeAttr(),
1768a25da1a9SValentin Clement                                         "vector_length")))
1769a25da1a9SValentin Clement     return failure();
1770a25da1a9SValentin Clement 
1771c09dc2d9SValentin Clement (バレンタイン クレメン)   if (failed(verifyDeviceTypeCountMatch(*this, getAsyncOperands(),
1772c09dc2d9SValentin Clement (バレンタイン クレメン)                                         getAsyncOperandsDeviceTypeAttr(),
1773c09dc2d9SValentin Clement (バレンタイン クレメン)                                         "async")))
1774c09dc2d9SValentin Clement (バレンタイン クレメン)     return failure();
1775c09dc2d9SValentin Clement (バレンタイン クレメン) 
1776c09dc2d9SValentin Clement (バレンタイン クレメン)   if (failed(checkWaitAndAsyncConflict<acc::KernelsOp>(*this)))
1777a25da1a9SValentin Clement     return failure();
1778a25da1a9SValentin Clement 
1779aad53e3bSValentin Clement   return checkDataOperands<acc::KernelsOp>(*this, getDataClauseOperands());
1780aad53e3bSValentin Clement }
1781aad53e3bSValentin Clement 
1782d56b74eaSValentin Clement //===----------------------------------------------------------------------===//
17835cbe3381SValentin Clement // HostDataOp
17845cbe3381SValentin Clement //===----------------------------------------------------------------------===//
17855cbe3381SValentin Clement 
17865cbe3381SValentin Clement LogicalResult acc::HostDataOp::verify() {
178720ba5c61SRazvan Lupusoru   if (getDataClauseOperands().empty())
17885cbe3381SValentin Clement     return emitError("at least one operand must appear on the host_data "
17895cbe3381SValentin Clement                      "operation");
17905cbe3381SValentin Clement 
179120ba5c61SRazvan Lupusoru   for (mlir::Value operand : getDataClauseOperands())
17925cbe3381SValentin Clement     if (!mlir::isa<acc::UseDeviceOp>(operand.getDefiningOp()))
17935cbe3381SValentin Clement       return emitError("expect data entry operation as defining op");
17945cbe3381SValentin Clement   return success();
17955cbe3381SValentin Clement }
17965cbe3381SValentin Clement 
1797c3c73e5dSValentin Clement void acc::HostDataOp::getCanonicalizationPatterns(RewritePatternSet &results,
1798c3c73e5dSValentin Clement                                                   MLIRContext *context) {
1799c3c73e5dSValentin Clement   results.add<RemoveConstantIfConditionWithRegion<HostDataOp>>(context);
1800c3c73e5dSValentin Clement }
1801c3c73e5dSValentin Clement 
18025cbe3381SValentin Clement //===----------------------------------------------------------------------===//
18034225e7faSValentin Clement // LoopOp
18044225e7faSValentin Clement //===----------------------------------------------------------------------===//
18054225e7faSValentin Clement 
1806e456689fSValentin Clement (バレンタイン クレメン) static ParseResult parseGangValue(
1807e456689fSValentin Clement (バレンタイン クレメン)     OpAsmParser &parser, llvm::StringRef keyword,
1808e456689fSValentin Clement (バレンタイン クレメン)     llvm::SmallVectorImpl<mlir::OpAsmParser::UnresolvedOperand> &operands,
1809e456689fSValentin Clement (バレンタイン クレメン)     llvm::SmallVectorImpl<Type> &types,
1810e456689fSValentin Clement (バレンタイン クレメン)     llvm::SmallVector<GangArgTypeAttr> &attributes, GangArgTypeAttr gangArgType,
181140f5f905SValentin Clement (バレンタイン クレメン)     bool &needCommaBetweenValues, bool &newValue) {
18122e69944aSValentin Clement   if (succeeded(parser.parseOptionalKeyword(keyword))) {
18132e69944aSValentin Clement     if (parser.parseEqual())
18142e69944aSValentin Clement       return failure();
1815e456689fSValentin Clement (バレンタイン クレメン)     if (parser.parseOperand(operands.emplace_back()) ||
1816e456689fSValentin Clement (バレンタイン クレメン)         parser.parseColonType(types.emplace_back()))
18172e69944aSValentin Clement       return failure();
1818e456689fSValentin Clement (バレンタイン クレメン)     attributes.push_back(gangArgType);
181940f5f905SValentin Clement (バレンタイン クレメン)     needCommaBetweenValues = true;
18202e69944aSValentin Clement     newValue = true;
18212e69944aSValentin Clement   }
18222e69944aSValentin Clement   return success();
18232e69944aSValentin Clement }
18242e69944aSValentin Clement 
18257f3d2cc2SValentin Clement static ParseResult parseGangClause(
1826e456689fSValentin Clement (バレンタイン クレメン)     OpAsmParser &parser,
1827e456689fSValentin Clement (バレンタイン クレメン)     llvm::SmallVectorImpl<mlir::OpAsmParser::UnresolvedOperand> &gangOperands,
1828e456689fSValentin Clement (バレンタイン クレメン)     llvm::SmallVectorImpl<Type> &gangOperandsType, mlir::ArrayAttr &gangArgType,
182940f5f905SValentin Clement (バレンタイン クレメン)     mlir::ArrayAttr &deviceType, mlir::DenseI32ArrayAttr &segments,
183040f5f905SValentin Clement (バレンタイン クレメン)     mlir::ArrayAttr &gangOnlyDeviceType) {
183140f5f905SValentin Clement (バレンタイン クレメン)   llvm::SmallVector<GangArgTypeAttr> gangArgTypeAttributes;
183240f5f905SValentin Clement (バレンタイン クレメン)   llvm::SmallVector<mlir::Attribute> deviceTypeAttributes;
183340f5f905SValentin Clement (バレンタイン クレメン)   llvm::SmallVector<mlir::Attribute> gangOnlyDeviceTypeAttributes;
1834e456689fSValentin Clement (バレンタイン クレメン)   llvm::SmallVector<int32_t> seg;
183540f5f905SValentin Clement (バレンタイン クレメン)   bool needCommaBetweenValues = false;
183640f5f905SValentin Clement (バレンタイン クレメン)   bool needCommaBeforeOperands = false;
183740f5f905SValentin Clement (バレンタイン クレメン) 
18386b42625bSValentin Clement (バレンタイン クレメン)   if (failed(parser.parseOptionalLParen())) {
18396b42625bSValentin Clement (バレンタイン クレメン)     // Gang only keyword
18406b42625bSValentin Clement (バレンタイン クレメン)     gangOnlyDeviceTypeAttributes.push_back(mlir::acc::DeviceTypeAttr::get(
18416b42625bSValentin Clement (バレンタイン クレメン)         parser.getContext(), mlir::acc::DeviceType::None));
18426b42625bSValentin Clement (バレンタイン クレメン)     gangOnlyDeviceType =
18436b42625bSValentin Clement (バレンタイン クレメン)         ArrayAttr::get(parser.getContext(), gangOnlyDeviceTypeAttributes);
18446b42625bSValentin Clement (バレンタイン クレメン)     return success();
18456b42625bSValentin Clement (バレンタイン クレメン)   }
184640f5f905SValentin Clement (バレンタイン クレメン) 
184740f5f905SValentin Clement (バレンタイン クレメン)   // Parse gang only attributes
184840f5f905SValentin Clement (バレンタイン クレメン)   if (succeeded(parser.parseOptionalLSquare())) {
18493eb4178bSValentin Clement (バレンタイン クレメン)     // Parse gang only attributes
185040f5f905SValentin Clement (バレンタイン クレメン)     if (failed(parser.parseCommaSeparatedList([&]() {
185140f5f905SValentin Clement (バレンタイン クレメン)           if (parser.parseAttribute(
185240f5f905SValentin Clement (バレンタイン クレメン)                   gangOnlyDeviceTypeAttributes.emplace_back()))
185340f5f905SValentin Clement (バレンタイン クレメン)             return failure();
185440f5f905SValentin Clement (バレンタイン クレメン)           return success();
185540f5f905SValentin Clement (バレンタイン クレメン)         })))
185640f5f905SValentin Clement (バレンタイン クレメン)       return failure();
185740f5f905SValentin Clement (バレンタイン クレメン)     if (parser.parseRSquare())
185840f5f905SValentin Clement (バレンタイン クレメン)       return failure();
185940f5f905SValentin Clement (バレンタイン クレメン)     needCommaBeforeOperands = true;
186040f5f905SValentin Clement (バレンタイン クレメン)   }
18612e69944aSValentin Clement 
1862e456689fSValentin Clement (バレンタイン クレメン)   auto argNum = mlir::acc::GangArgTypeAttr::get(parser.getContext(),
1863e456689fSValentin Clement (バレンタイン クレメン)                                                 mlir::acc::GangArgType::Num);
1864e456689fSValentin Clement (バレンタイン クレメン)   auto argDim = mlir::acc::GangArgTypeAttr::get(parser.getContext(),
1865e456689fSValentin Clement (バレンタイン クレメン)                                                 mlir::acc::GangArgType::Dim);
1866e456689fSValentin Clement (バレンタイン クレメン)   auto argStatic = mlir::acc::GangArgTypeAttr::get(
1867e456689fSValentin Clement (バレンタイン クレメン)       parser.getContext(), mlir::acc::GangArgType::Static);
1868e456689fSValentin Clement (バレンタイン クレメン) 
1869e456689fSValentin Clement (バレンタイン クレメン)   do {
187040f5f905SValentin Clement (バレンタイン クレメン)     if (needCommaBeforeOperands) {
187140f5f905SValentin Clement (バレンタイン クレメン)       needCommaBeforeOperands = false;
187240f5f905SValentin Clement (バレンタイン クレメン)       continue;
187340f5f905SValentin Clement (バレンタイン クレメン)     }
187440f5f905SValentin Clement (バレンタイン クレメン) 
1875e456689fSValentin Clement (バレンタイン クレメン)     if (failed(parser.parseLBrace()))
1876e456689fSValentin Clement (バレンタイン クレメン)       return failure();
1877e456689fSValentin Clement (バレンタイン クレメン) 
1878e456689fSValentin Clement (バレンタイン クレメン)     int32_t crtOperandsSize = gangOperands.size();
18792e69944aSValentin Clement     while (true) {
18802e69944aSValentin Clement       bool newValue = false;
18812e69944aSValentin Clement       bool needValue = false;
188240f5f905SValentin Clement (バレンタイン クレメン)       if (needCommaBetweenValues) {
18832e69944aSValentin Clement         if (succeeded(parser.parseOptionalComma()))
18842e69944aSValentin Clement           needValue = true; // expect a new value after comma.
18852e69944aSValentin Clement         else
18862e69944aSValentin Clement           break;
1887b6c1930dSValentin Clement       }
18882e69944aSValentin Clement 
1889e456689fSValentin Clement (バレンタイン クレメン)       if (failed(parseGangValue(parser, LoopOp::getGangNumKeyword(),
189040f5f905SValentin Clement (バレンタイン クレメン)                                 gangOperands, gangOperandsType,
189140f5f905SValentin Clement (バレンタイン クレメン)                                 gangArgTypeAttributes, argNum,
189240f5f905SValentin Clement (バレンタイン クレメン)                                 needCommaBetweenValues, newValue)))
18932bbbcae7SValentin Clement         return failure();
1894e456689fSValentin Clement (バレンタイン クレメン)       if (failed(parseGangValue(parser, LoopOp::getGangDimKeyword(),
189540f5f905SValentin Clement (バレンタイン クレメン)                                 gangOperands, gangOperandsType,
189640f5f905SValentin Clement (バレンタイン クレメン)                                 gangArgTypeAttributes, argDim,
189740f5f905SValentin Clement (バレンタイン クレメン)                                 needCommaBetweenValues, newValue)))
18987f3d2cc2SValentin Clement         return failure();
18992e69944aSValentin Clement       if (failed(parseGangValue(parser, LoopOp::getGangStaticKeyword(),
190040f5f905SValentin Clement (バレンタイン クレメン)                                 gangOperands, gangOperandsType,
190140f5f905SValentin Clement (バレンタイン クレメン)                                 gangArgTypeAttributes, argStatic,
190240f5f905SValentin Clement (バレンタイン クレメン)                                 needCommaBetweenValues, newValue)))
19032e69944aSValentin Clement         return failure();
19042e69944aSValentin Clement 
19052e69944aSValentin Clement       if (!newValue && needValue) {
19062e69944aSValentin Clement         parser.emitError(parser.getCurrentLocation(),
19072e69944aSValentin Clement                          "new value expected after comma");
1908b6c1930dSValentin Clement         return failure();
1909b6c1930dSValentin Clement       }
19102e69944aSValentin Clement 
19112e69944aSValentin Clement       if (!newValue)
19122e69944aSValentin Clement         break;
19132e69944aSValentin Clement     }
19142e69944aSValentin Clement 
1915e456689fSValentin Clement (バレンタイン クレメン)     if (gangOperands.empty())
1916e456689fSValentin Clement (バレンタイン クレメン)       return parser.emitError(
1917e456689fSValentin Clement (バレンタイン クレメン)           parser.getCurrentLocation(),
19187f3d2cc2SValentin Clement           "expect at least one of num, dim or static values");
1919e456689fSValentin Clement (バレンタイン クレメン) 
1920e456689fSValentin Clement (バレンタイン クレメン)     if (failed(parser.parseRBrace()))
19212e69944aSValentin Clement       return failure();
1922e456689fSValentin Clement (バレンタイン クレメン) 
1923e456689fSValentin Clement (バレンタイン クレメン)     if (succeeded(parser.parseOptionalLSquare())) {
1924e456689fSValentin Clement (バレンタイン クレメン)       if (parser.parseAttribute(deviceTypeAttributes.emplace_back()) ||
1925e456689fSValentin Clement (バレンタイン クレメン)           parser.parseRSquare())
1926e456689fSValentin Clement (バレンタイン クレメン)         return failure();
1927e456689fSValentin Clement (バレンタイン クレメン)     } else {
1928e456689fSValentin Clement (バレンタイン クレメン)       deviceTypeAttributes.push_back(mlir::acc::DeviceTypeAttr::get(
1929e456689fSValentin Clement (バレンタイン クレメン)           parser.getContext(), mlir::acc::DeviceType::None));
19302e69944aSValentin Clement     }
19312e69944aSValentin Clement 
1932e456689fSValentin Clement (バレンタイン クレメン)     seg.push_back(gangOperands.size() - crtOperandsSize);
1933e456689fSValentin Clement (バレンタイン クレメン) 
1934e456689fSValentin Clement (バレンタイン クレメン)   } while (succeeded(parser.parseOptionalComma()));
1935e456689fSValentin Clement (バレンタイン クレメン) 
193640f5f905SValentin Clement (バレンタイン クレメン)   if (failed(parser.parseRParen()))
193740f5f905SValentin Clement (バレンタイン クレメン)     return failure();
1938e456689fSValentin Clement (バレンタイン クレメン) 
193940f5f905SValentin Clement (バレンタイン クレメン)   llvm::SmallVector<mlir::Attribute> arrayAttr(gangArgTypeAttributes.begin(),
194040f5f905SValentin Clement (バレンタイン クレメン)                                                gangArgTypeAttributes.end());
194140f5f905SValentin Clement (バレンタイン クレメン)   gangArgType = ArrayAttr::get(parser.getContext(), arrayAttr);
194240f5f905SValentin Clement (バレンタイン クレメン)   deviceType = ArrayAttr::get(parser.getContext(), deviceTypeAttributes);
194340f5f905SValentin Clement (バレンタイン クレメン) 
194440f5f905SValentin Clement (バレンタイン クレメン)   llvm::SmallVector<mlir::Attribute> gangOnlyAttr(
194540f5f905SValentin Clement (バレンタイン クレメン)       gangOnlyDeviceTypeAttributes.begin(), gangOnlyDeviceTypeAttributes.end());
194640f5f905SValentin Clement (バレンタイン クレメン)   gangOnlyDeviceType = ArrayAttr::get(parser.getContext(), gangOnlyAttr);
194740f5f905SValentin Clement (バレンタイン クレメン) 
1948e456689fSValentin Clement (バレンタイン クレメン)   segments = DenseI32ArrayAttr::get(parser.getContext(), seg);
19494225e7faSValentin Clement   return success();
19504225e7faSValentin Clement }
19514225e7faSValentin Clement 
1952e456689fSValentin Clement (バレンタイン クレメン) void printGangClause(OpAsmPrinter &p, Operation *op,
1953e456689fSValentin Clement (バレンタイン クレメン)                      mlir::OperandRange operands, mlir::TypeRange types,
1954e456689fSValentin Clement (バレンタイン クレメン)                      std::optional<mlir::ArrayAttr> gangArgTypes,
1955e456689fSValentin Clement (バレンタイン クレメン)                      std::optional<mlir::ArrayAttr> deviceTypes,
195640f5f905SValentin Clement (バレンタイン クレメン)                      std::optional<mlir::DenseI32ArrayAttr> segments,
195740f5f905SValentin Clement (バレンタイン クレメン)                      std::optional<mlir::ArrayAttr> gangOnlyDeviceTypes) {
195840f5f905SValentin Clement (バレンタイン クレメン) 
1959b8967e00SValentin Clement (バレンタイン クレメン)   if (operands.begin() == operands.end() &&
196078ef0328SValentin Clement (バレンタイン クレメン)       hasOnlyDeviceTypeNone(gangOnlyDeviceTypes)) {
196140f5f905SValentin Clement (バレンタイン クレメン)     return;
196240f5f905SValentin Clement (バレンタイン クレメン)   }
196340f5f905SValentin Clement (バレンタイン クレメン) 
19646b42625bSValentin Clement (バレンタイン クレメン)   p << "(";
19656b42625bSValentin Clement (バレンタイン クレメン) 
1966bd5d41a3SValentin Clement (バレンタイン クレメン)   printDeviceTypes(p, gangOnlyDeviceTypes);
196740f5f905SValentin Clement (バレンタイン クレメン) 
196840f5f905SValentin Clement (バレンタイン クレメン)   if (hasDeviceTypeValues(gangOnlyDeviceTypes) &&
196940f5f905SValentin Clement (バレンタイン クレメン)       hasDeviceTypeValues(deviceTypes))
197040f5f905SValentin Clement (バレンタイン クレメン)     p << ", ";
197140f5f905SValentin Clement (バレンタイン クレメン) 
1972b8967e00SValentin Clement (バレンタイン クレメン)   if (hasDeviceTypeValues(deviceTypes)) {
1973e456689fSValentin Clement (バレンタイン クレメン)     unsigned opIdx = 0;
1974bd5d41a3SValentin Clement (バレンタイン クレメン)     llvm::interleaveComma(llvm::enumerate(*deviceTypes), p, [&](auto it) {
1975e456689fSValentin Clement (バレンタイン クレメン)       p << "{";
1976bd5d41a3SValentin Clement (バレンタイン クレメン)       llvm::interleaveComma(
1977bd5d41a3SValentin Clement (バレンタイン クレメン)           llvm::seq<int32_t>(0, (*segments)[it.index()]), p, [&](auto it) {
1978bd5d41a3SValentin Clement (バレンタイン クレメン)             auto gangArgTypeAttr = mlir::dyn_cast<mlir::acc::GangArgTypeAttr>(
1979bd5d41a3SValentin Clement (バレンタイン クレメン)                 (*gangArgTypes)[opIdx]);
1980e456689fSValentin Clement (バレンタイン クレメン)             if (gangArgTypeAttr.getValue() == mlir::acc::GangArgType::Num)
1981e456689fSValentin Clement (バレンタイン クレメン)               p << LoopOp::getGangNumKeyword();
1982e456689fSValentin Clement (バレンタイン クレメン)             else if (gangArgTypeAttr.getValue() == mlir::acc::GangArgType::Dim)
1983e456689fSValentin Clement (バレンタイン クレメン)               p << LoopOp::getGangDimKeyword();
1984bd5d41a3SValentin Clement (バレンタイン クレメン)             else if (gangArgTypeAttr.getValue() ==
1985bd5d41a3SValentin Clement (バレンタイン クレメン)                      mlir::acc::GangArgType::Static)
1986e456689fSValentin Clement (バレンタイン クレメン)               p << LoopOp::getGangStaticKeyword();
1987e456689fSValentin Clement (バレンタイン クレメン)             p << "=" << operands[opIdx] << " : " << operands[opIdx].getType();
1988e456689fSValentin Clement (バレンタイン クレメン)             ++opIdx;
1989bd5d41a3SValentin Clement (バレンタイン クレメン)           });
1990e456689fSValentin Clement (バレンタイン クレメン)       p << "}";
1991bd5d41a3SValentin Clement (バレンタイン クレメン)       printSingleDeviceType(p, it.value());
1992bd5d41a3SValentin Clement (バレンタイン クレメン)     });
19932bbbcae7SValentin Clement   }
199440f5f905SValentin Clement (バレンタイン クレメン)   p << ")";
199540f5f905SValentin Clement (バレンタイン クレメン) }
19964225e7faSValentin Clement 
1997e456689fSValentin Clement (バレンタイン クレメン) bool hasDuplicateDeviceTypes(
1998e456689fSValentin Clement (バレンタイン クレメン)     std::optional<mlir::ArrayAttr> segments,
1999e456689fSValentin Clement (バレンタイン クレメン)     llvm::SmallSet<mlir::acc::DeviceType, 3> &deviceTypes) {
2000e456689fSValentin Clement (バレンタイン クレメン)   if (!segments)
2001e456689fSValentin Clement (バレンタイン クレメン)     return false;
2002e456689fSValentin Clement (バレンタイン クレメン)   for (auto attr : *segments) {
2003e456689fSValentin Clement (バレンタイン クレメン)     auto deviceTypeAttr = mlir::dyn_cast<mlir::acc::DeviceTypeAttr>(attr);
20046f52c1e6SKazu Hirata     if (!deviceTypes.insert(deviceTypeAttr.getValue()).second)
2005e456689fSValentin Clement (バレンタイン クレメン)       return true;
2006e456689fSValentin Clement (バレンタイン クレメン)   }
2007e456689fSValentin Clement (バレンタイン クレメン)   return false;
2008e456689fSValentin Clement (バレンタイン クレメン) }
2009e456689fSValentin Clement (バレンタイン クレメン) 
2010e456689fSValentin Clement (バレンタイン クレメン) /// Check for duplicates in the DeviceType array attribute.
2011e456689fSValentin Clement (バレンタイン クレメン) LogicalResult checkDeviceTypes(mlir::ArrayAttr deviceTypes) {
2012e456689fSValentin Clement (バレンタイン クレメン)   llvm::SmallSet<mlir::acc::DeviceType, 3> crtDeviceTypes;
2013e456689fSValentin Clement (バレンタイン クレメン)   if (!deviceTypes)
2014e456689fSValentin Clement (バレンタイン クレメン)     return success();
2015e456689fSValentin Clement (バレンタイン クレメン)   for (auto attr : deviceTypes) {
2016e456689fSValentin Clement (バレンタイン クレメン)     auto deviceTypeAttr =
2017e456689fSValentin Clement (バレンタイン クレメン)         mlir::dyn_cast_or_null<mlir::acc::DeviceTypeAttr>(attr);
2018e456689fSValentin Clement (バレンタイン クレメン)     if (!deviceTypeAttr)
2019b6c1930dSValentin Clement       return failure();
20206f52c1e6SKazu Hirata     if (!crtDeviceTypes.insert(deviceTypeAttr.getValue()).second)
2021e456689fSValentin Clement (バレンタイン クレメン)       return failure();
2022b6c1930dSValentin Clement   }
2023b6c1930dSValentin Clement   return success();
20242bbbcae7SValentin Clement }
20252bbbcae7SValentin Clement 
2026ef72cf44SRiver Riddle LogicalResult acc::LoopOp::verify() {
20273eb4178bSValentin Clement (バレンタイン クレメン)   if (!getUpperbound().empty() && getInclusiveUpperbound() &&
20283eb4178bSValentin Clement (バレンタイン クレメン)       (getUpperbound().size() != getInclusiveUpperbound()->size()))
20293eb4178bSValentin Clement (バレンタイン クレメン)     return emitError() << "inclusiveUpperbound size is expected to be the same"
20303eb4178bSValentin Clement (バレンタイン クレメン)                        << " as upperbound size";
20313eb4178bSValentin Clement (バレンタイン クレメン) 
2032e456689fSValentin Clement (バレンタイン クレメン)   // Check collapse
2033e456689fSValentin Clement (バレンタイン クレメン)   if (getCollapseAttr() && !getCollapseDeviceTypeAttr())
2034e456689fSValentin Clement (バレンタイン クレメン)     return emitOpError() << "collapse device_type attr must be define when"
2035e456689fSValentin Clement (バレンタイン クレメン)                          << " collapse attr is present";
2036e456689fSValentin Clement (バレンタイン クレメン) 
2037e456689fSValentin Clement (バレンタイン クレメン)   if (getCollapseAttr() && getCollapseDeviceTypeAttr() &&
2038e456689fSValentin Clement (バレンタイン クレメン)       getCollapseAttr().getValue().size() !=
2039e456689fSValentin Clement (バレンタイン クレメン)           getCollapseDeviceTypeAttr().getValue().size())
2040e456689fSValentin Clement (バレンタイン クレメン)     return emitOpError() << "collapse attribute count must match collapse"
2041e456689fSValentin Clement (バレンタイン クレメン)                          << " device_type count";
2042e456689fSValentin Clement (バレンタイン クレメン)   if (failed(checkDeviceTypes(getCollapseDeviceTypeAttr())))
2043e456689fSValentin Clement (バレンタイン クレメン)     return emitOpError()
2044e456689fSValentin Clement (バレンタイン クレメン)            << "duplicate device_type found in collapseDeviceType attribute";
2045e456689fSValentin Clement (バレンタイン クレメン) 
2046e456689fSValentin Clement (バレンタイン クレメン)   // Check gang
2047e456689fSValentin Clement (バレンタイン クレメン)   if (!getGangOperands().empty()) {
2048e456689fSValentin Clement (バレンタイン クレメン)     if (!getGangOperandsArgType())
2049e456689fSValentin Clement (バレンタイン クレメン)       return emitOpError() << "gangOperandsArgType attribute must be defined"
2050e456689fSValentin Clement (バレンタイン クレメン)                            << " when gang operands are present";
2051e456689fSValentin Clement (バレンタイン クレメン) 
2052e456689fSValentin Clement (バレンタイン クレメン)     if (getGangOperands().size() !=
2053e456689fSValentin Clement (バレンタイン クレメン)         getGangOperandsArgTypeAttr().getValue().size())
2054e456689fSValentin Clement (バレンタイン クレメン)       return emitOpError() << "gangOperandsArgType attribute count must match"
2055e456689fSValentin Clement (バレンタイン クレメン)                            << " gangOperands count";
2056e456689fSValentin Clement (バレンタイン クレメン)   }
2057e456689fSValentin Clement (バレンタイン クレメン)   if (getGangAttr() && failed(checkDeviceTypes(getGangAttr())))
2058e456689fSValentin Clement (バレンタイン クレメン)     return emitOpError() << "duplicate device_type found in gang attribute";
2059e456689fSValentin Clement (バレンタイン クレメン) 
2060e456689fSValentin Clement (バレンタイン クレメン)   if (failed(verifyDeviceTypeAndSegmentCountMatch(
2061e456689fSValentin Clement (バレンタイン クレメン)           *this, getGangOperands(), getGangOperandsSegmentsAttr(),
2062e456689fSValentin Clement (バレンタイン クレメン)           getGangOperandsDeviceTypeAttr(), "gang")))
2063e456689fSValentin Clement (バレンタイン クレメン)     return failure();
2064e456689fSValentin Clement (バレンタイン クレメン) 
2065e456689fSValentin Clement (バレンタイン クレメン)   // Check worker
2066e456689fSValentin Clement (バレンタイン クレメン)   if (failed(checkDeviceTypes(getWorkerAttr())))
2067e456689fSValentin Clement (バレンタイン クレメン)     return emitOpError() << "duplicate device_type found in worker attribute";
2068e456689fSValentin Clement (バレンタイン クレメン)   if (failed(checkDeviceTypes(getWorkerNumOperandsDeviceTypeAttr())))
2069e456689fSValentin Clement (バレンタイン クレメン)     return emitOpError() << "duplicate device_type found in "
2070e456689fSValentin Clement (バレンタイン クレメン)                             "workerNumOperandsDeviceType attribute";
2071e456689fSValentin Clement (バレンタイン クレメン)   if (failed(verifyDeviceTypeCountMatch(*this, getWorkerNumOperands(),
2072e456689fSValentin Clement (バレンタイン クレメン)                                         getWorkerNumOperandsDeviceTypeAttr(),
2073e456689fSValentin Clement (バレンタイン クレメン)                                         "worker")))
2074e456689fSValentin Clement (バレンタイン クレメン)     return failure();
2075e456689fSValentin Clement (バレンタイン クレメン) 
2076e456689fSValentin Clement (バレンタイン クレメン)   // Check vector
2077e456689fSValentin Clement (バレンタイン クレメン)   if (failed(checkDeviceTypes(getVectorAttr())))
2078e456689fSValentin Clement (バレンタイン クレメン)     return emitOpError() << "duplicate device_type found in vector attribute";
2079e456689fSValentin Clement (バレンタイン クレメン)   if (failed(checkDeviceTypes(getVectorOperandsDeviceTypeAttr())))
2080e456689fSValentin Clement (バレンタイン クレメン)     return emitOpError() << "duplicate device_type found in "
2081e456689fSValentin Clement (バレンタイン クレメン)                             "vectorOperandsDeviceType attribute";
2082e456689fSValentin Clement (バレンタイン クレメン)   if (failed(verifyDeviceTypeCountMatch(*this, getVectorOperands(),
2083e456689fSValentin Clement (バレンタイン クレメン)                                         getVectorOperandsDeviceTypeAttr(),
2084e456689fSValentin Clement (バレンタイン クレメン)                                         "vector")))
2085e456689fSValentin Clement (バレンタイン クレメン)     return failure();
2086e456689fSValentin Clement (バレンタイン クレメン) 
2087e456689fSValentin Clement (バレンタイン クレメン)   if (failed(verifyDeviceTypeAndSegmentCountMatch(
2088e456689fSValentin Clement (バレンタイン クレメン)           *this, getTileOperands(), getTileOperandsSegmentsAttr(),
2089e456689fSValentin Clement (バレンタイン クレメン)           getTileOperandsDeviceTypeAttr(), "tile")))
2090e456689fSValentin Clement (バレンタイン クレメン)     return failure();
2091e456689fSValentin Clement (バレンタイン クレメン) 
209201f5fcd8SValentin Clement   // auto, independent and seq attribute are mutually exclusive.
2093e456689fSValentin Clement (バレンタイン クレメン)   llvm::SmallSet<mlir::acc::DeviceType, 3> deviceTypes;
2094e456689fSValentin Clement (バレンタイン クレメン)   if (hasDuplicateDeviceTypes(getAuto_(), deviceTypes) ||
2095e456689fSValentin Clement (バレンタイン クレメン)       hasDuplicateDeviceTypes(getIndependent(), deviceTypes) ||
2096e456689fSValentin Clement (バレンタイン クレメン)       hasDuplicateDeviceTypes(getSeq(), deviceTypes)) {
2097b6c1930dSValentin Clement     return emitError() << "only one of \"" << acc::LoopOp::getAutoAttrStrName()
2098b6c1930dSValentin Clement                        << "\", " << getIndependentAttrName() << ", "
2099b6c1930dSValentin Clement                        << getSeqAttrName()
2100b6c1930dSValentin Clement                        << " can be present at the same time";
210101f5fcd8SValentin Clement   }
210201f5fcd8SValentin Clement 
210301f5fcd8SValentin Clement   // Gang, worker and vector are incompatible with seq.
2104e456689fSValentin Clement (バレンタイン クレメン)   if (getSeqAttr()) {
2105e456689fSValentin Clement (バレンタイン クレメン)     for (auto attr : getSeqAttr()) {
2106e456689fSValentin Clement (バレンタイン クレメン)       auto deviceTypeAttr = mlir::dyn_cast<mlir::acc::DeviceTypeAttr>(attr);
2107e456689fSValentin Clement (バレンタイン クレメン)       if (hasVector(deviceTypeAttr.getValue()) ||
2108e456689fSValentin Clement (バレンタイン クレメン)           getVectorValue(deviceTypeAttr.getValue()) ||
2109e456689fSValentin Clement (バレンタイン クレメン)           hasWorker(deviceTypeAttr.getValue()) ||
2110e456689fSValentin Clement (バレンタイン クレメン)           getWorkerValue(deviceTypeAttr.getValue()) ||
2111e456689fSValentin Clement (バレンタイン クレメン)           hasGang(deviceTypeAttr.getValue()) ||
2112e456689fSValentin Clement (バレンタイン クレメン)           getGangValue(mlir::acc::GangArgType::Num,
2113e456689fSValentin Clement (バレンタイン クレメン)                        deviceTypeAttr.getValue()) ||
2114e456689fSValentin Clement (バレンタイン クレメン)           getGangValue(mlir::acc::GangArgType::Dim,
2115e456689fSValentin Clement (バレンタイン クレメン)                        deviceTypeAttr.getValue()) ||
2116e456689fSValentin Clement (バレンタイン クレメン)           getGangValue(mlir::acc::GangArgType::Static,
2117e456689fSValentin Clement (バレンタイン クレメン)                        deviceTypeAttr.getValue()))
2118e456689fSValentin Clement (バレンタイン クレメン)         return emitError()
2119e456689fSValentin Clement (バレンタイン クレメン)                << "gang, worker or vector cannot appear with the seq attr";
2120e456689fSValentin Clement (バレンタイン クレメン)     }
2121e456689fSValentin Clement (バレンタイン クレメン)   }
212201f5fcd8SValentin Clement 
2123f4f53f8bSValentin Clement   if (failed(checkSymOperandList<mlir::acc::PrivateRecipeOp>(
2124f4f53f8bSValentin Clement           *this, getPrivatizations(), getPrivateOperands(), "private",
212549f1232eSValentin Clement (バレンタイン クレメン)           "privatizations", false)))
2126d2fddaefSValentin Clement     return failure();
2127d2fddaefSValentin Clement 
21286763f591SValentin Clement   if (failed(checkSymOperandList<mlir::acc::ReductionRecipeOp>(
21296763f591SValentin Clement           *this, getReductionRecipes(), getReductionOperands(), "reduction",
213059ceb7ddSValentin Clement           "reductions", false)))
21316763f591SValentin Clement     return failure();
21326763f591SValentin Clement 
2133a435e1f6SRazvan Lupusoru   if (getCombined().has_value() &&
2134a435e1f6SRazvan Lupusoru       (getCombined().value() != acc::CombinedConstructsType::ParallelLoop &&
2135a435e1f6SRazvan Lupusoru        getCombined().value() != acc::CombinedConstructsType::KernelsLoop &&
2136a435e1f6SRazvan Lupusoru        getCombined().value() != acc::CombinedConstructsType::SerialLoop)) {
2137a435e1f6SRazvan Lupusoru     return emitError("unexpected combined constructs attribute");
2138a435e1f6SRazvan Lupusoru   }
2139a435e1f6SRazvan Lupusoru 
214001f5fcd8SValentin Clement   // Check non-empty body().
2141f9806b3eSRiver Riddle   if (getRegion().empty())
2142ef72cf44SRiver Riddle     return emitError("expected non-empty body.");
214301f5fcd8SValentin Clement 
214401f5fcd8SValentin Clement   return success();
214501f5fcd8SValentin Clement }
214601f5fcd8SValentin Clement 
2147f5a51425SRazvan Lupusoru unsigned LoopOp::getNumDataOperands() {
2148f5a51425SRazvan Lupusoru   return getReductionOperands().size() + getPrivateOperands().size();
2149f5a51425SRazvan Lupusoru }
2150f5a51425SRazvan Lupusoru 
2151f5a51425SRazvan Lupusoru Value LoopOp::getDataOperand(unsigned i) {
21523eb4178bSValentin Clement (バレンタイン クレメン)   unsigned numOptional =
21533eb4178bSValentin Clement (バレンタイン クレメン)       getLowerbound().size() + getUpperbound().size() + getStep().size();
21543eb4178bSValentin Clement (バレンタイン クレメン)   numOptional += getGangOperands().size();
2155e456689fSValentin Clement (バレンタイン クレメン)   numOptional += getVectorOperands().size();
2156e456689fSValentin Clement (バレンタイン クレメン)   numOptional += getWorkerNumOperands().size();
2157f5a51425SRazvan Lupusoru   numOptional += getTileOperands().size();
2158f5a51425SRazvan Lupusoru   numOptional += getCacheOperands().size();
2159f5a51425SRazvan Lupusoru   return getOperand(numOptional + i);
2160f5a51425SRazvan Lupusoru }
2161f5a51425SRazvan Lupusoru 
2162e456689fSValentin Clement (バレンタイン クレメン) bool LoopOp::hasAuto() { return hasAuto(mlir::acc::DeviceType::None); }
2163e456689fSValentin Clement (バレンタイン クレメン) 
2164e456689fSValentin Clement (バレンタイン クレメン) bool LoopOp::hasAuto(mlir::acc::DeviceType deviceType) {
2165ee6199caSValentin Clement (バレンタイン クレメン)   return hasDeviceType(getAuto_(), deviceType);
2166e456689fSValentin Clement (バレンタイン クレメン) }
2167e456689fSValentin Clement (バレンタイン クレメン) 
2168e456689fSValentin Clement (バレンタイン クレメン) bool LoopOp::hasIndependent() {
2169e456689fSValentin Clement (バレンタイン クレメン)   return hasIndependent(mlir::acc::DeviceType::None);
2170e456689fSValentin Clement (バレンタイン クレメン) }
2171e456689fSValentin Clement (バレンタイン クレメン) 
2172e456689fSValentin Clement (バレンタイン クレメン) bool LoopOp::hasIndependent(mlir::acc::DeviceType deviceType) {
2173ee6199caSValentin Clement (バレンタイン クレメン)   return hasDeviceType(getIndependent(), deviceType);
2174e456689fSValentin Clement (バレンタイン クレメン) }
2175e456689fSValentin Clement (バレンタイン クレメン) 
2176e456689fSValentin Clement (バレンタイン クレメン) bool LoopOp::hasSeq() { return hasSeq(mlir::acc::DeviceType::None); }
2177e456689fSValentin Clement (バレンタイン クレメン) 
2178e456689fSValentin Clement (バレンタイン クレメン) bool LoopOp::hasSeq(mlir::acc::DeviceType deviceType) {
2179ee6199caSValentin Clement (バレンタイン クレメン)   return hasDeviceType(getSeq(), deviceType);
2180e456689fSValentin Clement (バレンタイン クレメン) }
2181e456689fSValentin Clement (バレンタイン クレメン) 
2182e456689fSValentin Clement (バレンタイン クレメン) mlir::Value LoopOp::getVectorValue() {
2183e456689fSValentin Clement (バレンタイン クレメン)   return getVectorValue(mlir::acc::DeviceType::None);
2184e456689fSValentin Clement (バレンタイン クレメン) }
2185e456689fSValentin Clement (バレンタイン クレメン) 
2186e456689fSValentin Clement (バレンタイン クレメン) mlir::Value LoopOp::getVectorValue(mlir::acc::DeviceType deviceType) {
2187e456689fSValentin Clement (バレンタイン クレメン)   return getValueInDeviceTypeSegment(getVectorOperandsDeviceType(),
2188e456689fSValentin Clement (バレンタイン クレメン)                                      getVectorOperands(), deviceType);
2189e456689fSValentin Clement (バレンタイン クレメン) }
2190e456689fSValentin Clement (バレンタイン クレメン) 
2191e456689fSValentin Clement (バレンタイン クレメン) bool LoopOp::hasVector() { return hasVector(mlir::acc::DeviceType::None); }
2192e456689fSValentin Clement (バレンタイン クレメン) 
2193e456689fSValentin Clement (バレンタイン クレメン) bool LoopOp::hasVector(mlir::acc::DeviceType deviceType) {
2194ee6199caSValentin Clement (バレンタイン クレメン)   return hasDeviceType(getVector(), deviceType);
2195e456689fSValentin Clement (バレンタイン クレメン) }
2196e456689fSValentin Clement (バレンタイン クレメン) 
2197e456689fSValentin Clement (バレンタイン クレメン) mlir::Value LoopOp::getWorkerValue() {
2198e456689fSValentin Clement (バレンタイン クレメン)   return getWorkerValue(mlir::acc::DeviceType::None);
2199e456689fSValentin Clement (バレンタイン クレメン) }
2200e456689fSValentin Clement (バレンタイン クレメン) 
2201e456689fSValentin Clement (バレンタイン クレメン) mlir::Value LoopOp::getWorkerValue(mlir::acc::DeviceType deviceType) {
2202e456689fSValentin Clement (バレンタイン クレメン)   return getValueInDeviceTypeSegment(getWorkerNumOperandsDeviceType(),
2203e456689fSValentin Clement (バレンタイン クレメン)                                      getWorkerNumOperands(), deviceType);
2204e456689fSValentin Clement (バレンタイン クレメン) }
2205e456689fSValentin Clement (バレンタイン クレメン) 
2206e456689fSValentin Clement (バレンタイン クレメン) bool LoopOp::hasWorker() { return hasWorker(mlir::acc::DeviceType::None); }
2207e456689fSValentin Clement (バレンタイン クレメン) 
2208e456689fSValentin Clement (バレンタイン クレメン) bool LoopOp::hasWorker(mlir::acc::DeviceType deviceType) {
2209ee6199caSValentin Clement (バレンタイン クレメン)   return hasDeviceType(getWorker(), deviceType);
2210e456689fSValentin Clement (バレンタイン クレメン) }
2211e456689fSValentin Clement (バレンタイン クレメン) 
2212e456689fSValentin Clement (バレンタイン クレメン) mlir::Operation::operand_range LoopOp::getTileValues() {
2213e456689fSValentin Clement (バレンタイン クレメン)   return getTileValues(mlir::acc::DeviceType::None);
2214e456689fSValentin Clement (バレンタイン クレメン) }
2215e456689fSValentin Clement (バレンタイン クレメン) 
2216e456689fSValentin Clement (バレンタイン クレメン) mlir::Operation::operand_range
2217e456689fSValentin Clement (バレンタイン クレメン) LoopOp::getTileValues(mlir::acc::DeviceType deviceType) {
2218e456689fSValentin Clement (バレンタイン クレメン)   return getValuesFromSegments(getTileOperandsDeviceType(), getTileOperands(),
2219e456689fSValentin Clement (バレンタイン クレメン)                                getTileOperandsSegments(), deviceType);
2220e456689fSValentin Clement (バレンタイン クレメン) }
2221e456689fSValentin Clement (バレンタイン クレメン) 
2222e456689fSValentin Clement (バレンタイン クレメン) std::optional<int64_t> LoopOp::getCollapseValue() {
2223e456689fSValentin Clement (バレンタイン クレメン)   return getCollapseValue(mlir::acc::DeviceType::None);
2224e456689fSValentin Clement (バレンタイン クレメン) }
2225e456689fSValentin Clement (バレンタイン クレメン) 
2226e456689fSValentin Clement (バレンタイン クレメン) std::optional<int64_t>
2227e456689fSValentin Clement (バレンタイン クレメン) LoopOp::getCollapseValue(mlir::acc::DeviceType deviceType) {
2228e456689fSValentin Clement (バレンタイン クレメン)   if (!getCollapseAttr())
2229e456689fSValentin Clement (バレンタイン クレメン)     return std::nullopt;
2230e456689fSValentin Clement (バレンタイン クレメン)   if (auto pos = findSegment(getCollapseDeviceTypeAttr(), deviceType)) {
2231e456689fSValentin Clement (バレンタイン クレメン)     auto intAttr =
2232e456689fSValentin Clement (バレンタイン クレメン)         mlir::dyn_cast<IntegerAttr>(getCollapseAttr().getValue()[*pos]);
2233e456689fSValentin Clement (バレンタイン クレメン)     return intAttr.getValue().getZExtValue();
2234e456689fSValentin Clement (バレンタイン クレメン)   }
2235e456689fSValentin Clement (バレンタイン クレメン)   return std::nullopt;
2236e456689fSValentin Clement (バレンタイン クレメン) }
2237e456689fSValentin Clement (バレンタイン クレメン) 
2238e456689fSValentin Clement (バレンタイン クレメン) mlir::Value LoopOp::getGangValue(mlir::acc::GangArgType gangArgType) {
2239e456689fSValentin Clement (バレンタイン クレメン)   return getGangValue(gangArgType, mlir::acc::DeviceType::None);
2240e456689fSValentin Clement (バレンタイン クレメン) }
2241e456689fSValentin Clement (バレンタイン クレメン) 
2242e456689fSValentin Clement (バレンタイン クレメン) mlir::Value LoopOp::getGangValue(mlir::acc::GangArgType gangArgType,
2243e456689fSValentin Clement (バレンタイン クレメン)                                  mlir::acc::DeviceType deviceType) {
2244e456689fSValentin Clement (バレンタイン クレメン)   if (getGangOperands().empty())
2245e456689fSValentin Clement (バレンタイン クレメン)     return {};
2246e456689fSValentin Clement (バレンタイン クレメン)   if (auto pos = findSegment(*getGangOperandsDeviceType(), deviceType)) {
2247e456689fSValentin Clement (バレンタイン クレメン)     int32_t nbOperandsBefore = 0;
2248e456689fSValentin Clement (バレンタイン クレメン)     for (unsigned i = 0; i < *pos; ++i)
2249e456689fSValentin Clement (バレンタイン クレメン)       nbOperandsBefore += (*getGangOperandsSegments())[i];
2250e456689fSValentin Clement (バレンタイン クレメン)     mlir::Operation::operand_range values =
2251e456689fSValentin Clement (バレンタイン クレメン)         getGangOperands()
2252e456689fSValentin Clement (バレンタイン クレメン)             .drop_front(nbOperandsBefore)
2253e456689fSValentin Clement (バレンタイン クレメン)             .take_front((*getGangOperandsSegments())[*pos]);
2254e456689fSValentin Clement (バレンタイン クレメン) 
2255e456689fSValentin Clement (バレンタイン クレメン)     int32_t argTypeIdx = nbOperandsBefore;
2256e456689fSValentin Clement (バレンタイン クレメン)     for (auto value : values) {
2257e456689fSValentin Clement (バレンタイン クレメン)       auto gangArgTypeAttr = mlir::dyn_cast<mlir::acc::GangArgTypeAttr>(
2258e456689fSValentin Clement (バレンタイン クレメン)           (*getGangOperandsArgType())[argTypeIdx]);
2259e456689fSValentin Clement (バレンタイン クレメン)       if (gangArgTypeAttr.getValue() == gangArgType)
2260e456689fSValentin Clement (バレンタイン クレメン)         return value;
2261e456689fSValentin Clement (バレンタイン クレメン)       ++argTypeIdx;
2262e456689fSValentin Clement (バレンタイン クレメン)     }
2263e456689fSValentin Clement (バレンタイン クレメン)   }
2264e456689fSValentin Clement (バレンタイン クレメン)   return {};
2265e456689fSValentin Clement (バレンタイン クレメン) }
2266e456689fSValentin Clement (バレンタイン クレメン) 
2267e456689fSValentin Clement (バレンタイン クレメン) bool LoopOp::hasGang() { return hasGang(mlir::acc::DeviceType::None); }
2268e456689fSValentin Clement (バレンタイン クレメン) 
2269e456689fSValentin Clement (バレンタイン クレメン) bool LoopOp::hasGang(mlir::acc::DeviceType deviceType) {
2270ee6199caSValentin Clement (バレンタイン クレメン)   return hasDeviceType(getGang(), deviceType);
2271e456689fSValentin Clement (バレンタイン クレメン) }
2272e456689fSValentin Clement (バレンタイン クレメン) 
22733eb4178bSValentin Clement (バレンタイン クレメン) llvm::SmallVector<mlir::Region *> acc::LoopOp::getLoopRegions() {
22743eb4178bSValentin Clement (バレンタイン クレメン)   return {&getRegion()};
22753eb4178bSValentin Clement (バレンタイン クレメン) }
22763eb4178bSValentin Clement (バレンタイン クレメン) 
22776b42625bSValentin Clement (バレンタイン クレメン) /// loop-control ::= `control` `(` ssa-id-and-type-list `)` `=`
22786b42625bSValentin Clement (バレンタイン クレメン) /// `(` ssa-id-and-type-list `)` `to` `(` ssa-id-and-type-list `)` `step`
22796b42625bSValentin Clement (バレンタイン クレメン) /// `(` ssa-id-and-type-list `)`
22806b42625bSValentin Clement (バレンタイン クレメン) /// region
22813eb4178bSValentin Clement (バレンタイン クレメン) ParseResult
22823eb4178bSValentin Clement (バレンタイン クレメン) parseLoopControl(OpAsmParser &parser, Region &region,
22833eb4178bSValentin Clement (バレンタイン クレメン)                  SmallVectorImpl<OpAsmParser::UnresolvedOperand> &lowerbound,
22843eb4178bSValentin Clement (バレンタイン クレメン)                  SmallVectorImpl<Type> &lowerboundType,
22853eb4178bSValentin Clement (バレンタイン クレメン)                  SmallVectorImpl<OpAsmParser::UnresolvedOperand> &upperbound,
22863eb4178bSValentin Clement (バレンタイン クレメン)                  SmallVectorImpl<Type> &upperboundType,
22873eb4178bSValentin Clement (バレンタイン クレメン)                  SmallVectorImpl<OpAsmParser::UnresolvedOperand> &step,
22883eb4178bSValentin Clement (バレンタイン クレメン)                  SmallVectorImpl<Type> &stepType) {
22893eb4178bSValentin Clement (バレンタイン クレメン) 
22903eb4178bSValentin Clement (バレンタイン クレメン)   SmallVector<OpAsmParser::Argument> inductionVars;
22916b42625bSValentin Clement (バレンタイン クレメン)   if (succeeded(
22926b42625bSValentin Clement (バレンタイン クレメン)           parser.parseOptionalKeyword(acc::LoopOp::getControlKeyword()))) {
22936b42625bSValentin Clement (バレンタイン クレメン)     if (parser.parseLParen() ||
22946b42625bSValentin Clement (バレンタイン クレメン)         parser.parseArgumentList(inductionVars, OpAsmParser::Delimiter::None,
22953eb4178bSValentin Clement (バレンタイン クレメン)                                  /*allowType=*/true) ||
22963eb4178bSValentin Clement (バレンタイン クレメン)         parser.parseRParen() || parser.parseEqual() || parser.parseLParen() ||
22973eb4178bSValentin Clement (バレンタイン クレメン)         parser.parseOperandList(lowerbound, inductionVars.size(),
22983eb4178bSValentin Clement (バレンタイン クレメン)                                 OpAsmParser::Delimiter::None) ||
22993eb4178bSValentin Clement (バレンタイン クレメン)         parser.parseColonTypeList(lowerboundType) || parser.parseRParen() ||
23003eb4178bSValentin Clement (バレンタイン クレメン)         parser.parseKeyword("to") || parser.parseLParen() ||
23013eb4178bSValentin Clement (バレンタイン クレメン)         parser.parseOperandList(upperbound, inductionVars.size(),
23023eb4178bSValentin Clement (バレンタイン クレメン)                                 OpAsmParser::Delimiter::None) ||
23033eb4178bSValentin Clement (バレンタイン クレメン)         parser.parseColonTypeList(upperboundType) || parser.parseRParen() ||
23043eb4178bSValentin Clement (バレンタイン クレメン)         parser.parseKeyword("step") || parser.parseLParen() ||
23053eb4178bSValentin Clement (バレンタイン クレメン)         parser.parseOperandList(step, inductionVars.size(),
23063eb4178bSValentin Clement (バレンタイン クレメン)                                 OpAsmParser::Delimiter::None) ||
23073eb4178bSValentin Clement (バレンタイン クレメン)         parser.parseColonTypeList(stepType) || parser.parseRParen())
23083eb4178bSValentin Clement (バレンタイン クレメン)       return failure();
23093eb4178bSValentin Clement (バレンタイン クレメン)   }
23103eb4178bSValentin Clement (バレンタイン クレメン)   return parser.parseRegion(region, inductionVars);
23113eb4178bSValentin Clement (バレンタイン クレメン) }
23123eb4178bSValentin Clement (バレンタイン クレメン) 
23133eb4178bSValentin Clement (バレンタイン クレメン) void printLoopControl(OpAsmPrinter &p, Operation *op, Region &region,
23143eb4178bSValentin Clement (バレンタイン クレメン)                       ValueRange lowerbound, TypeRange lowerboundType,
23153eb4178bSValentin Clement (バレンタイン クレメン)                       ValueRange upperbound, TypeRange upperboundType,
23163eb4178bSValentin Clement (バレンタイン クレメン)                       ValueRange steps, TypeRange stepType) {
23173eb4178bSValentin Clement (バレンタイン クレメン)   ValueRange regionArgs = region.front().getArguments();
23183eb4178bSValentin Clement (バレンタイン クレメン)   if (!regionArgs.empty()) {
23196b42625bSValentin Clement (バレンタイン クレメン)     p << acc::LoopOp::getControlKeyword() << "(";
23203eb4178bSValentin Clement (バレンタイン クレメン)     llvm::interleaveComma(regionArgs, p,
23213eb4178bSValentin Clement (バレンタイン クレメン)                           [&p](Value v) { p << v << " : " << v.getType(); });
23223eb4178bSValentin Clement (バレンタイン クレメン)     p << ") = (" << lowerbound << " : " << lowerboundType << ") to ("
23238d5ba759SVijay Kandiah       << upperbound << " : " << upperboundType << ") " << " step (" << steps
23248d5ba759SVijay Kandiah       << " : " << stepType << ") ";
23253eb4178bSValentin Clement (バレンタイン クレメン)   }
23263eb4178bSValentin Clement (バレンタイン クレメン)   p.printRegion(region, /*printEntryBlockArgs=*/false);
23273eb4178bSValentin Clement (バレンタイン クレメン) }
23283eb4178bSValentin Clement (バレンタイン クレメン) 
2329bbb5dc49SValentin Clement //===----------------------------------------------------------------------===//
2330bbb5dc49SValentin Clement // DataOp
2331bbb5dc49SValentin Clement //===----------------------------------------------------------------------===//
2332bbb5dc49SValentin Clement 
2333ef72cf44SRiver Riddle LogicalResult acc::DataOp::verify() {
2334bbb5dc49SValentin Clement   // 2.6.5. Data Construct restriction
2335bbb5dc49SValentin Clement   // At least one copy, copyin, copyout, create, no_create, present, deviceptr,
2336bbb5dc49SValentin Clement   // attach, or default clause must appear on a data construct.
2337f9806b3eSRiver Riddle   if (getOperands().empty() && !getDefaultAttr())
2338ef72cf44SRiver Riddle     return emitError("at least one operand or the default attribute "
2339bbb5dc49SValentin Clement                      "must appear on the data operation");
2340a7b50effSValentin Clement 
2341a7b50effSValentin Clement   for (mlir::Value operand : getDataClauseOperands())
2342a7b50effSValentin Clement     if (!mlir::isa<acc::AttachOp, acc::CopyinOp, acc::CopyoutOp, acc::CreateOp,
2343a7b50effSValentin Clement                    acc::DeleteOp, acc::DetachOp, acc::DevicePtrOp,
2344a7b50effSValentin Clement                    acc::GetDevicePtrOp, acc::NoCreateOp, acc::PresentOp>(
2345a7b50effSValentin Clement             operand.getDefiningOp()))
2346a7b50effSValentin Clement       return emitError("expect data entry/exit operation or acc.getdeviceptr "
2347a7b50effSValentin Clement                        "as defining op");
2348a7b50effSValentin Clement 
2349c09dc2d9SValentin Clement (バレンタイン クレメン)   if (failed(checkWaitAndAsyncConflict<acc::DataOp>(*this)))
2350c09dc2d9SValentin Clement (バレンタイン クレメン)     return failure();
2351c09dc2d9SValentin Clement (バレンタイン クレメン) 
2352ecc99780SValentin Clement   return success();
2353ecc99780SValentin Clement }
2354ecc99780SValentin Clement 
235546e1b095SValentin Clement unsigned DataOp::getNumDataOperands() { return getDataClauseOperands().size(); }
2356fcb15472SValentin Clement 
2357fcb15472SValentin Clement Value DataOp::getDataOperand(unsigned i) {
2358f9806b3eSRiver Riddle   unsigned numOptional = getIfCond() ? 1 : 0;
2359c09dc2d9SValentin Clement (バレンタイン クレメン)   numOptional += getAsyncOperands().size() ? 1 : 0;
236061807f5cSValentin Clement   numOptional += getWaitOperands().size();
2361fcb15472SValentin Clement   return getOperand(numOptional + i);
2362fcb15472SValentin Clement }
2363fcb15472SValentin Clement 
236471ec3013SValentin Clement (バレンタイン クレメン) bool acc::DataOp::hasAsyncOnly() {
236571ec3013SValentin Clement (バレンタイン クレメン)   return hasAsyncOnly(mlir::acc::DeviceType::None);
236671ec3013SValentin Clement (バレンタイン クレメン) }
236771ec3013SValentin Clement (バレンタイン クレメン) 
236871ec3013SValentin Clement (バレンタイン クレメン) bool acc::DataOp::hasAsyncOnly(mlir::acc::DeviceType deviceType) {
2369ee6199caSValentin Clement (バレンタイン クレメン)   return hasDeviceType(getAsyncOnly(), deviceType);
237071ec3013SValentin Clement (バレンタイン クレメン) }
237171ec3013SValentin Clement (バレンタイン クレメン) 
237271ec3013SValentin Clement (バレンタイン クレメン) mlir::Value DataOp::getAsyncValue() {
237371ec3013SValentin Clement (バレンタイン クレメン)   return getAsyncValue(mlir::acc::DeviceType::None);
237471ec3013SValentin Clement (バレンタイン クレメン) }
237571ec3013SValentin Clement (バレンタイン クレメン) 
237671ec3013SValentin Clement (バレンタイン クレメン) mlir::Value DataOp::getAsyncValue(mlir::acc::DeviceType deviceType) {
2377c09dc2d9SValentin Clement (バレンタイン クレメン)   return getValueInDeviceTypeSegment(getAsyncOperandsDeviceType(),
2378c09dc2d9SValentin Clement (バレンタイン クレメン)                                      getAsyncOperands(), deviceType);
237971ec3013SValentin Clement (バレンタイン クレメン) }
238071ec3013SValentin Clement (バレンタイン クレメン) 
238171ec3013SValentin Clement (バレンタイン クレメン) bool DataOp::hasWaitOnly() { return hasWaitOnly(mlir::acc::DeviceType::None); }
238271ec3013SValentin Clement (バレンタイン クレメン) 
238371ec3013SValentin Clement (バレンタイン クレメン) bool DataOp::hasWaitOnly(mlir::acc::DeviceType deviceType) {
2384ee6199caSValentin Clement (バレンタイン クレメン)   return hasDeviceType(getWaitOnly(), deviceType);
238571ec3013SValentin Clement (バレンタイン クレメン) }
238671ec3013SValentin Clement (バレンタイン クレメン) 
238771ec3013SValentin Clement (バレンタイン クレメン) mlir::Operation::operand_range DataOp::getWaitValues() {
238871ec3013SValentin Clement (バレンタイン クレメン)   return getWaitValues(mlir::acc::DeviceType::None);
238971ec3013SValentin Clement (バレンタイン クレメン) }
239071ec3013SValentin Clement (バレンタイン クレメン) 
239171ec3013SValentin Clement (バレンタイン クレメン) mlir::Operation::operand_range
239271ec3013SValentin Clement (バレンタイン クレメン) DataOp::getWaitValues(mlir::acc::DeviceType deviceType) {
2393c09dc2d9SValentin Clement (バレンタイン クレメン)   return getWaitValuesWithoutDevnum(
2394c09dc2d9SValentin Clement (バレンタイン クレメン)       getWaitOperandsDeviceType(), getWaitOperands(), getWaitOperandsSegments(),
2395c09dc2d9SValentin Clement (バレンタイン クレメン)       getHasWaitDevnum(), deviceType);
2396c09dc2d9SValentin Clement (バレンタイン クレメン) }
2397c09dc2d9SValentin Clement (バレンタイン クレメン) 
2398c09dc2d9SValentin Clement (バレンタイン クレメン) mlir::Value DataOp::getWaitDevnum() {
2399c09dc2d9SValentin Clement (バレンタイン クレメン)   return getWaitDevnum(mlir::acc::DeviceType::None);
2400c09dc2d9SValentin Clement (バレンタイン クレメン) }
2401c09dc2d9SValentin Clement (バレンタイン クレメン) 
2402c09dc2d9SValentin Clement (バレンタイン クレメン) mlir::Value DataOp::getWaitDevnum(mlir::acc::DeviceType deviceType) {
2403c09dc2d9SValentin Clement (バレンタイン クレメン)   return getWaitDevnumValue(getWaitOperandsDeviceType(), getWaitOperands(),
2404c09dc2d9SValentin Clement (バレンタイン クレメン)                             getWaitOperandsSegments(), getHasWaitDevnum(),
2405c09dc2d9SValentin Clement (バレンタイン クレメン)                             deviceType);
240671ec3013SValentin Clement (バレンタイン クレメン) }
240771ec3013SValentin Clement (バレンタイン クレメン) 
2408ecc99780SValentin Clement //===----------------------------------------------------------------------===//
24096260cb1dSValentin Clement // ExitDataOp
24106260cb1dSValentin Clement //===----------------------------------------------------------------------===//
24116260cb1dSValentin Clement 
2412ef72cf44SRiver Riddle LogicalResult acc::ExitDataOp::verify() {
24136260cb1dSValentin Clement   // 2.6.6. Data Exit Directive restriction
24146260cb1dSValentin Clement   // At least one copyout, delete, or detach clause must appear on an exit data
24156260cb1dSValentin Clement   // directive.
241615a480c0SValentin Clement   if (getDataClauseOperands().empty())
241715a480c0SValentin Clement     return emitError("at least one operand must be present in dataOperands on "
241815a480c0SValentin Clement                      "the exit data operation");
24196260cb1dSValentin Clement 
24206260cb1dSValentin Clement   // The async attribute represent the async clause without value. Therefore the
24216260cb1dSValentin Clement   // attribute and operand cannot appear at the same time.
2422f9806b3eSRiver Riddle   if (getAsyncOperand() && getAsync())
2423ef72cf44SRiver Riddle     return emitError("async attribute cannot appear with asyncOperand");
24246260cb1dSValentin Clement 
24256260cb1dSValentin Clement   // The wait attribute represent the wait clause without values. Therefore the
24266260cb1dSValentin Clement   // attribute and operands cannot appear at the same time.
2427f9806b3eSRiver Riddle   if (!getWaitOperands().empty() && getWait())
2428ef72cf44SRiver Riddle     return emitError("wait attribute cannot appear with waitOperands");
24296260cb1dSValentin Clement 
2430f9806b3eSRiver Riddle   if (getWaitDevnum() && getWaitOperands().empty())
2431ef72cf44SRiver Riddle     return emitError("wait_devnum cannot appear without waitOperands");
24326260cb1dSValentin Clement 
24336260cb1dSValentin Clement   return success();
24346260cb1dSValentin Clement }
24356260cb1dSValentin Clement 
24366110b667SValentin Clement unsigned ExitDataOp::getNumDataOperands() {
243715a480c0SValentin Clement   return getDataClauseOperands().size();
24386110b667SValentin Clement }
24396110b667SValentin Clement 
24406110b667SValentin Clement Value ExitDataOp::getDataOperand(unsigned i) {
2441f9806b3eSRiver Riddle   unsigned numOptional = getIfCond() ? 1 : 0;
2442f9806b3eSRiver Riddle   numOptional += getAsyncOperand() ? 1 : 0;
2443f9806b3eSRiver Riddle   numOptional += getWaitDevnum() ? 1 : 0;
2444f9806b3eSRiver Riddle   return getOperand(getWaitOperands().size() + numOptional + i);
24456110b667SValentin Clement }
24466110b667SValentin Clement 
2447aa4e6a60SValentin Clement void ExitDataOp::getCanonicalizationPatterns(RewritePatternSet &results,
2448aa4e6a60SValentin Clement                                              MLIRContext *context) {
2449aa4e6a60SValentin Clement   results.add<RemoveConstantIfCondition<ExitDataOp>>(context);
2450aa4e6a60SValentin Clement }
2451aa4e6a60SValentin Clement 
24526260cb1dSValentin Clement //===----------------------------------------------------------------------===//
24536110b667SValentin Clement // EnterDataOp
24544b011901SValentin Clement //===----------------------------------------------------------------------===//
24554b011901SValentin Clement 
2456ef72cf44SRiver Riddle LogicalResult acc::EnterDataOp::verify() {
24574b011901SValentin Clement   // 2.6.6. Data Enter Directive restriction
24584b011901SValentin Clement   // At least one copyin, create, or attach clause must appear on an enter data
24594b011901SValentin Clement   // directive.
24609dec07f4SValentin Clement   if (getDataClauseOperands().empty())
24619dec07f4SValentin Clement     return emitError("at least one operand must be present in dataOperands on "
24629dec07f4SValentin Clement                      "the enter data operation");
24634b011901SValentin Clement 
24644b011901SValentin Clement   // The async attribute represent the async clause without value. Therefore the
24654b011901SValentin Clement   // attribute and operand cannot appear at the same time.
2466f9806b3eSRiver Riddle   if (getAsyncOperand() && getAsync())
2467ef72cf44SRiver Riddle     return emitError("async attribute cannot appear with asyncOperand");
24684b011901SValentin Clement 
24694b011901SValentin Clement   // The wait attribute represent the wait clause without values. Therefore the
24704b011901SValentin Clement   // attribute and operands cannot appear at the same time.
2471f9806b3eSRiver Riddle   if (!getWaitOperands().empty() && getWait())
2472ef72cf44SRiver Riddle     return emitError("wait attribute cannot appear with waitOperands");
24734b011901SValentin Clement 
2474f9806b3eSRiver Riddle   if (getWaitDevnum() && getWaitOperands().empty())
2475ef72cf44SRiver Riddle     return emitError("wait_devnum cannot appear without waitOperands");
24764b011901SValentin Clement 
24777cb96299SValentin Clement   for (mlir::Value operand : getDataClauseOperands())
24787cb96299SValentin Clement     if (!mlir::isa<acc::AttachOp, acc::CreateOp, acc::CopyinOp>(
24797cb96299SValentin Clement             operand.getDefiningOp()))
24807cb96299SValentin Clement       return emitError("expect data entry operation as defining op");
24817cb96299SValentin Clement 
24824b011901SValentin Clement   return success();
24834b011901SValentin Clement }
24844b011901SValentin Clement 
24856110b667SValentin Clement unsigned EnterDataOp::getNumDataOperands() {
24869dec07f4SValentin Clement   return getDataClauseOperands().size();
24876110b667SValentin Clement }
24886110b667SValentin Clement 
24896110b667SValentin Clement Value EnterDataOp::getDataOperand(unsigned i) {
2490f9806b3eSRiver Riddle   unsigned numOptional = getIfCond() ? 1 : 0;
2491f9806b3eSRiver Riddle   numOptional += getAsyncOperand() ? 1 : 0;
2492f9806b3eSRiver Riddle   numOptional += getWaitDevnum() ? 1 : 0;
2493f9806b3eSRiver Riddle   return getOperand(getWaitOperands().size() + numOptional + i);
24946110b667SValentin Clement }
24956110b667SValentin Clement 
2496aa4e6a60SValentin Clement void EnterDataOp::getCanonicalizationPatterns(RewritePatternSet &results,
2497aa4e6a60SValentin Clement                                               MLIRContext *context) {
2498aa4e6a60SValentin Clement   results.add<RemoveConstantIfCondition<EnterDataOp>>(context);
2499aa4e6a60SValentin Clement }
2500aa4e6a60SValentin Clement 
25014b011901SValentin Clement //===----------------------------------------------------------------------===//
250261278ec3SRazvan Lupusoru // AtomicReadOp
250361278ec3SRazvan Lupusoru //===----------------------------------------------------------------------===//
250461278ec3SRazvan Lupusoru 
25054983432fSChristian Ulmann LogicalResult AtomicReadOp::verify() { return verifyCommon(); }
250661278ec3SRazvan Lupusoru 
250761278ec3SRazvan Lupusoru //===----------------------------------------------------------------------===//
250861278ec3SRazvan Lupusoru // AtomicWriteOp
250961278ec3SRazvan Lupusoru //===----------------------------------------------------------------------===//
251061278ec3SRazvan Lupusoru 
25114983432fSChristian Ulmann LogicalResult AtomicWriteOp::verify() { return verifyCommon(); }
251261278ec3SRazvan Lupusoru 
251361278ec3SRazvan Lupusoru //===----------------------------------------------------------------------===//
251461278ec3SRazvan Lupusoru // AtomicUpdateOp
251561278ec3SRazvan Lupusoru //===----------------------------------------------------------------------===//
251661278ec3SRazvan Lupusoru 
251761278ec3SRazvan Lupusoru LogicalResult AtomicUpdateOp::canonicalize(AtomicUpdateOp op,
251861278ec3SRazvan Lupusoru                                            PatternRewriter &rewriter) {
251961278ec3SRazvan Lupusoru   if (op.isNoOp()) {
252061278ec3SRazvan Lupusoru     rewriter.eraseOp(op);
252161278ec3SRazvan Lupusoru     return success();
252261278ec3SRazvan Lupusoru   }
252361278ec3SRazvan Lupusoru 
252461278ec3SRazvan Lupusoru   if (Value writeVal = op.getWriteOpVal()) {
252561278ec3SRazvan Lupusoru     rewriter.replaceOpWithNewOp<AtomicWriteOp>(op, op.getX(), writeVal);
252661278ec3SRazvan Lupusoru     return success();
252761278ec3SRazvan Lupusoru   }
252861278ec3SRazvan Lupusoru 
252961278ec3SRazvan Lupusoru   return failure();
253061278ec3SRazvan Lupusoru }
253161278ec3SRazvan Lupusoru 
25324983432fSChristian Ulmann LogicalResult AtomicUpdateOp::verify() { return verifyCommon(); }
253361278ec3SRazvan Lupusoru 
25344983432fSChristian Ulmann LogicalResult AtomicUpdateOp::verifyRegions() { return verifyRegionsCommon(); }
253561278ec3SRazvan Lupusoru 
253661278ec3SRazvan Lupusoru //===----------------------------------------------------------------------===//
253761278ec3SRazvan Lupusoru // AtomicCaptureOp
253861278ec3SRazvan Lupusoru //===----------------------------------------------------------------------===//
253961278ec3SRazvan Lupusoru 
254061278ec3SRazvan Lupusoru AtomicReadOp AtomicCaptureOp::getAtomicReadOp() {
254161278ec3SRazvan Lupusoru   if (auto op = dyn_cast<AtomicReadOp>(getFirstOp()))
254261278ec3SRazvan Lupusoru     return op;
254361278ec3SRazvan Lupusoru   return dyn_cast<AtomicReadOp>(getSecondOp());
254461278ec3SRazvan Lupusoru }
254561278ec3SRazvan Lupusoru 
254661278ec3SRazvan Lupusoru AtomicWriteOp AtomicCaptureOp::getAtomicWriteOp() {
254761278ec3SRazvan Lupusoru   if (auto op = dyn_cast<AtomicWriteOp>(getFirstOp()))
254861278ec3SRazvan Lupusoru     return op;
254961278ec3SRazvan Lupusoru   return dyn_cast<AtomicWriteOp>(getSecondOp());
255061278ec3SRazvan Lupusoru }
255161278ec3SRazvan Lupusoru 
255261278ec3SRazvan Lupusoru AtomicUpdateOp AtomicCaptureOp::getAtomicUpdateOp() {
255361278ec3SRazvan Lupusoru   if (auto op = dyn_cast<AtomicUpdateOp>(getFirstOp()))
255461278ec3SRazvan Lupusoru     return op;
255561278ec3SRazvan Lupusoru   return dyn_cast<AtomicUpdateOp>(getSecondOp());
255661278ec3SRazvan Lupusoru }
255761278ec3SRazvan Lupusoru 
25584983432fSChristian Ulmann LogicalResult AtomicCaptureOp::verifyRegions() { return verifyRegionsCommon(); }
255961278ec3SRazvan Lupusoru 
256061278ec3SRazvan Lupusoru //===----------------------------------------------------------------------===//
25617496177dSRazvan Lupusoru // DeclareEnterOp
25627496177dSRazvan Lupusoru //===----------------------------------------------------------------------===//
25637496177dSRazvan Lupusoru 
25647496177dSRazvan Lupusoru template <typename Op>
25659365ed1eSValentin Clement (バレンタイン クレメン) static LogicalResult
25669365ed1eSValentin Clement (バレンタイン クレメン) checkDeclareOperands(Op &op, const mlir::ValueRange &operands,
25679365ed1eSValentin Clement (バレンタイン クレメン)                      bool requireAtLeastOneOperand = true) {
25689365ed1eSValentin Clement (バレンタイン クレメン)   if (operands.empty() && requireAtLeastOneOperand)
25697496177dSRazvan Lupusoru     return emitError(
25707496177dSRazvan Lupusoru         op->getLoc(),
25717496177dSRazvan Lupusoru         "at least one operand must appear on the declare operation");
25727496177dSRazvan Lupusoru 
2573132c376aSRazvan Lupusoru   for (mlir::Value operand : operands) {
25747496177dSRazvan Lupusoru     if (!mlir::isa<acc::CopyinOp, acc::CopyoutOp, acc::CreateOp,
25757496177dSRazvan Lupusoru                    acc::DevicePtrOp, acc::GetDevicePtrOp, acc::PresentOp,
25767496177dSRazvan Lupusoru                    acc::DeclareDeviceResidentOp, acc::DeclareLinkOp>(
25777496177dSRazvan Lupusoru             operand.getDefiningOp()))
25787496177dSRazvan Lupusoru       return op.emitError(
25797496177dSRazvan Lupusoru           "expect valid declare data entry operation or acc.getdeviceptr "
25807496177dSRazvan Lupusoru           "as defining op");
2581132c376aSRazvan Lupusoru 
2582132c376aSRazvan Lupusoru     mlir::Value varPtr{getVarPtr(operand.getDefiningOp())};
2583132c376aSRazvan Lupusoru     assert(varPtr && "declare operands can only be data entry operations which "
2584132c376aSRazvan Lupusoru                      "must have varPtr");
2585132c376aSRazvan Lupusoru     std::optional<mlir::acc::DataClause> dataClauseOptional{
2586132c376aSRazvan Lupusoru         getDataClause(operand.getDefiningOp())};
2587132c376aSRazvan Lupusoru     assert(dataClauseOptional.has_value() &&
2588132c376aSRazvan Lupusoru            "declare operands can only be data entry operations which must have "
2589132c376aSRazvan Lupusoru            "dataClause");
2590132c376aSRazvan Lupusoru 
2591132c376aSRazvan Lupusoru     // If varPtr has no defining op - there is nothing to check further.
2592132c376aSRazvan Lupusoru     if (!varPtr.getDefiningOp())
2593132c376aSRazvan Lupusoru       continue;
2594132c376aSRazvan Lupusoru 
2595132c376aSRazvan Lupusoru     // Check that the varPtr has a declare attribute.
2596132c376aSRazvan Lupusoru     auto declareAttribute{
2597132c376aSRazvan Lupusoru         varPtr.getDefiningOp()->getAttr(mlir::acc::getDeclareAttrName())};
2598132c376aSRazvan Lupusoru     if (!declareAttribute)
2599132c376aSRazvan Lupusoru       return op.emitError(
2600132c376aSRazvan Lupusoru           "expect declare attribute on variable in declare operation");
26014bdc9057SRazvan Lupusoru 
26024bdc9057SRazvan Lupusoru     auto declAttr = mlir::cast<mlir::acc::DeclareAttr>(declareAttribute);
26034bdc9057SRazvan Lupusoru     if (declAttr.getDataClause().getValue() != dataClauseOptional.value())
2604132c376aSRazvan Lupusoru       return op.emitError(
2605132c376aSRazvan Lupusoru           "expect matching declare attribute on variable in declare operation");
26064bdc9057SRazvan Lupusoru 
26074bdc9057SRazvan Lupusoru     // If the variable is marked with implicit attribute, the matching declare
26084bdc9057SRazvan Lupusoru     // data action must also be marked implicit. The reverse is not checked
26094bdc9057SRazvan Lupusoru     // since implicit data action may be inserted to do actions like updating
26104bdc9057SRazvan Lupusoru     // device copy, in which case the variable is not necessarily implicitly
26114bdc9057SRazvan Lupusoru     // declare'd.
26124bdc9057SRazvan Lupusoru     if (declAttr.getImplicit() &&
26134bdc9057SRazvan Lupusoru         declAttr.getImplicit() != acc::getImplicitFlag(operand.getDefiningOp()))
26144bdc9057SRazvan Lupusoru       return op.emitError(
26154bdc9057SRazvan Lupusoru           "implicitness must match between declare op and flag on variable");
2616132c376aSRazvan Lupusoru   }
2617132c376aSRazvan Lupusoru 
26187496177dSRazvan Lupusoru   return success();
26197496177dSRazvan Lupusoru }
26207496177dSRazvan Lupusoru 
26217496177dSRazvan Lupusoru LogicalResult acc::DeclareEnterOp::verify() {
26227496177dSRazvan Lupusoru   return checkDeclareOperands(*this, this->getDataClauseOperands());
26237496177dSRazvan Lupusoru }
26247496177dSRazvan Lupusoru 
26257496177dSRazvan Lupusoru //===----------------------------------------------------------------------===//
26267496177dSRazvan Lupusoru // DeclareExitOp
26277496177dSRazvan Lupusoru //===----------------------------------------------------------------------===//
26287496177dSRazvan Lupusoru 
26297496177dSRazvan Lupusoru LogicalResult acc::DeclareExitOp::verify() {
26309365ed1eSValentin Clement (バレンタイン クレメン)   if (getToken())
26319365ed1eSValentin Clement (バレンタイン クレメン)     return checkDeclareOperands(*this, this->getDataClauseOperands(),
26329365ed1eSValentin Clement (バレンタイン クレメン)                                 /*requireAtLeastOneOperand=*/false);
26337496177dSRazvan Lupusoru   return checkDeclareOperands(*this, this->getDataClauseOperands());
26347496177dSRazvan Lupusoru }
26357496177dSRazvan Lupusoru 
26367496177dSRazvan Lupusoru //===----------------------------------------------------------------------===//
2637804b9979SValentin Clement // DeclareOp
2638804b9979SValentin Clement //===----------------------------------------------------------------------===//
2639804b9979SValentin Clement 
2640804b9979SValentin Clement LogicalResult acc::DeclareOp::verify() {
2641804b9979SValentin Clement   return checkDeclareOperands(*this, this->getDataClauseOperands());
2642804b9979SValentin Clement }
2643804b9979SValentin Clement 
2644804b9979SValentin Clement //===----------------------------------------------------------------------===//
264552a0b6a6SRazvan Lupusoru // RoutineOp
264652a0b6a6SRazvan Lupusoru //===----------------------------------------------------------------------===//
264752a0b6a6SRazvan Lupusoru 
2648b06bc7c6SValentin Clement (バレンタイン クレメン) static unsigned getParallelismForDeviceType(acc::RoutineOp op,
2649b06bc7c6SValentin Clement (バレンタイン クレメン)                                             acc::DeviceType dtype) {
2650b06bc7c6SValentin Clement (バレンタイン クレメン)   unsigned parallelism = 0;
2651b06bc7c6SValentin Clement (バレンタイン クレメン)   parallelism += (op.hasGang(dtype) || op.getGangDimValue(dtype)) ? 1 : 0;
2652b06bc7c6SValentin Clement (バレンタイン クレメン)   parallelism += op.hasWorker(dtype) ? 1 : 0;
2653b06bc7c6SValentin Clement (バレンタイン クレメン)   parallelism += op.hasVector(dtype) ? 1 : 0;
2654b06bc7c6SValentin Clement (バレンタイン クレメン)   parallelism += op.hasSeq(dtype) ? 1 : 0;
2655b06bc7c6SValentin Clement (バレンタイン クレメン)   return parallelism;
2656b06bc7c6SValentin Clement (バレンタイン クレメン) }
2657b06bc7c6SValentin Clement (バレンタイン クレメン) 
2658b06bc7c6SValentin Clement (バレンタイン クレメン) LogicalResult acc::RoutineOp::verify() {
2659b06bc7c6SValentin Clement (バレンタイン クレメン)   unsigned baseParallelism =
2660b06bc7c6SValentin Clement (バレンタイン クレメン)       getParallelismForDeviceType(*this, acc::DeviceType::None);
2661b06bc7c6SValentin Clement (バレンタイン クレメン) 
2662b06bc7c6SValentin Clement (バレンタイン クレメン)   if (baseParallelism > 1)
266352a0b6a6SRazvan Lupusoru     return emitError() << "only one of `gang`, `worker`, `vector`, `seq` can "
266452a0b6a6SRazvan Lupusoru                           "be present at the same time";
266552a0b6a6SRazvan Lupusoru 
2666b06bc7c6SValentin Clement (バレンタイン クレメン)   for (uint32_t dtypeInt = 0; dtypeInt != acc::getMaxEnumValForDeviceType();
2667b06bc7c6SValentin Clement (バレンタイン クレメン)        ++dtypeInt) {
2668b06bc7c6SValentin Clement (バレンタイン クレメン)     auto dtype = static_cast<acc::DeviceType>(dtypeInt);
2669b06bc7c6SValentin Clement (バレンタイン クレメン)     if (dtype == acc::DeviceType::None)
2670b06bc7c6SValentin Clement (バレンタイン クレメン)       continue;
2671b06bc7c6SValentin Clement (バレンタイン クレメン)     unsigned parallelism = getParallelismForDeviceType(*this, dtype);
2672b06bc7c6SValentin Clement (バレンタイン クレメン) 
2673b06bc7c6SValentin Clement (バレンタイン クレメン)     if (parallelism > 1 || (baseParallelism == 1 && parallelism == 1))
2674b06bc7c6SValentin Clement (バレンタイン クレメン)       return emitError() << "only one of `gang`, `worker`, `vector`, `seq` can "
2675b06bc7c6SValentin Clement (バレンタイン クレメン)                             "be present at the same time";
2676b06bc7c6SValentin Clement (バレンタイン クレメン)   }
2677b06bc7c6SValentin Clement (バレンタイン クレメン) 
267852a0b6a6SRazvan Lupusoru   return success();
267952a0b6a6SRazvan Lupusoru }
268052a0b6a6SRazvan Lupusoru 
2681b06bc7c6SValentin Clement (バレンタイン クレメン) static ParseResult parseBindName(OpAsmParser &parser, mlir::ArrayAttr &bindName,
2682b06bc7c6SValentin Clement (バレンタイン クレメン)                                  mlir::ArrayAttr &deviceTypes) {
2683b06bc7c6SValentin Clement (バレンタイン クレメン)   llvm::SmallVector<mlir::Attribute> bindNameAttrs;
2684b06bc7c6SValentin Clement (バレンタイン クレメン)   llvm::SmallVector<mlir::Attribute> deviceTypeAttrs;
268552a0b6a6SRazvan Lupusoru 
2686b06bc7c6SValentin Clement (バレンタイン クレメン)   if (failed(parser.parseCommaSeparatedList([&]() {
2687b06bc7c6SValentin Clement (バレンタイン クレメン)         if (parser.parseAttribute(bindNameAttrs.emplace_back()))
2688b06bc7c6SValentin Clement (バレンタイン クレメン)           return failure();
2689b06bc7c6SValentin Clement (バレンタイン クレメン)         if (failed(parser.parseOptionalLSquare())) {
2690b06bc7c6SValentin Clement (バレンタイン クレメン)           deviceTypeAttrs.push_back(mlir::acc::DeviceTypeAttr::get(
2691b06bc7c6SValentin Clement (バレンタイン クレメン)               parser.getContext(), mlir::acc::DeviceType::None));
2692b06bc7c6SValentin Clement (バレンタイン クレメン)         } else {
2693b06bc7c6SValentin Clement (バレンタイン クレメン)           if (parser.parseAttribute(deviceTypeAttrs.emplace_back()) ||
2694b06bc7c6SValentin Clement (バレンタイン クレメン)               parser.parseRSquare())
2695b06bc7c6SValentin Clement (バレンタイン クレメン)             return failure();
2696b06bc7c6SValentin Clement (バレンタイン クレメン)         }
2697b06bc7c6SValentin Clement (バレンタイン クレメン)         return success();
2698b06bc7c6SValentin Clement (バレンタイン クレメン)       })))
269952a0b6a6SRazvan Lupusoru     return failure();
270052a0b6a6SRazvan Lupusoru 
2701b06bc7c6SValentin Clement (バレンタイン クレメン)   bindName = ArrayAttr::get(parser.getContext(), bindNameAttrs);
2702b06bc7c6SValentin Clement (バレンタイン クレメン)   deviceTypes = ArrayAttr::get(parser.getContext(), deviceTypeAttrs);
2703b06bc7c6SValentin Clement (バレンタイン クレメン) 
2704b06bc7c6SValentin Clement (バレンタイン クレメン)   return success();
2705b06bc7c6SValentin Clement (バレンタイン クレメン) }
2706b06bc7c6SValentin Clement (バレンタイン クレメン) 
2707b06bc7c6SValentin Clement (バレンタイン クレメン) static void printBindName(mlir::OpAsmPrinter &p, mlir::Operation *op,
2708b06bc7c6SValentin Clement (バレンタイン クレメン)                           std::optional<mlir::ArrayAttr> bindName,
2709b06bc7c6SValentin Clement (バレンタイン クレメン)                           std::optional<mlir::ArrayAttr> deviceTypes) {
2710b06bc7c6SValentin Clement (バレンタイン クレメン)   llvm::interleaveComma(llvm::zip(*bindName, *deviceTypes), p,
2711b06bc7c6SValentin Clement (バレンタイン クレメン)                         [&](const auto &pair) {
2712b06bc7c6SValentin Clement (バレンタイン クレメン)                           p << std::get<0>(pair);
2713b06bc7c6SValentin Clement (バレンタイン クレメン)                           printSingleDeviceType(p, std::get<1>(pair));
2714b06bc7c6SValentin Clement (バレンタイン クレメン)                         });
2715b06bc7c6SValentin Clement (バレンタイン クレメン) }
2716b06bc7c6SValentin Clement (バレンタイン クレメン) 
2717b06bc7c6SValentin Clement (バレンタイン クレメン) static ParseResult parseRoutineGangClause(OpAsmParser &parser,
2718b06bc7c6SValentin Clement (バレンタイン クレメン)                                           mlir::ArrayAttr &gang,
2719b06bc7c6SValentin Clement (バレンタイン クレメン)                                           mlir::ArrayAttr &gangDim,
2720b06bc7c6SValentin Clement (バレンタイン クレメン)                                           mlir::ArrayAttr &gangDimDeviceTypes) {
2721b06bc7c6SValentin Clement (バレンタイン クレメン) 
2722b06bc7c6SValentin Clement (バレンタイン クレメン)   llvm::SmallVector<mlir::Attribute> gangAttrs, gangDimAttrs,
2723b06bc7c6SValentin Clement (バレンタイン クレメン)       gangDimDeviceTypeAttrs;
2724b06bc7c6SValentin Clement (バレンタイン クレメン)   bool needCommaBeforeOperands = false;
2725b06bc7c6SValentin Clement (バレンタイン クレメン) 
2726b06bc7c6SValentin Clement (バレンタイン クレメン)   // Gang keyword only
2727b06bc7c6SValentin Clement (バレンタイン クレメン)   if (failed(parser.parseOptionalLParen())) {
2728b06bc7c6SValentin Clement (バレンタイン クレメン)     gangAttrs.push_back(mlir::acc::DeviceTypeAttr::get(
2729b06bc7c6SValentin Clement (バレンタイン クレメン)         parser.getContext(), mlir::acc::DeviceType::None));
2730b06bc7c6SValentin Clement (バレンタイン クレメン)     gang = ArrayAttr::get(parser.getContext(), gangAttrs);
2731b06bc7c6SValentin Clement (バレンタイン クレメン)     return success();
2732b06bc7c6SValentin Clement (バレンタイン クレメン)   }
2733b06bc7c6SValentin Clement (バレンタイン クレメン) 
2734b06bc7c6SValentin Clement (バレンタイン クレメン)   // Parse keyword only attributes
2735b06bc7c6SValentin Clement (バレンタイン クレメン)   if (succeeded(parser.parseOptionalLSquare())) {
2736b06bc7c6SValentin Clement (バレンタイン クレメン)     if (failed(parser.parseCommaSeparatedList([&]() {
2737b06bc7c6SValentin Clement (バレンタイン クレメン)           if (parser.parseAttribute(gangAttrs.emplace_back()))
2738b06bc7c6SValentin Clement (バレンタイン クレメン)             return failure();
2739b06bc7c6SValentin Clement (バレンタイン クレメン)           return success();
2740b06bc7c6SValentin Clement (バレンタイン クレメン)         })))
2741b06bc7c6SValentin Clement (バレンタイン クレメン)       return failure();
2742b06bc7c6SValentin Clement (バレンタイン クレメン)     if (parser.parseRSquare())
2743b06bc7c6SValentin Clement (バレンタイン クレメン)       return failure();
2744b06bc7c6SValentin Clement (バレンタイン クレメン)     needCommaBeforeOperands = true;
2745b06bc7c6SValentin Clement (バレンタイン クレメン)   }
2746b06bc7c6SValentin Clement (バレンタイン クレメン) 
2747b06bc7c6SValentin Clement (バレンタイン クレメン)   if (needCommaBeforeOperands && failed(parser.parseComma()))
274852a0b6a6SRazvan Lupusoru     return failure();
274952a0b6a6SRazvan Lupusoru 
2750b06bc7c6SValentin Clement (バレンタイン クレメン)   if (failed(parser.parseCommaSeparatedList([&]() {
2751b06bc7c6SValentin Clement (バレンタイン クレメン)         if (parser.parseKeyword(acc::RoutineOp::getGangDimKeyword()) ||
2752b06bc7c6SValentin Clement (バレンタイン クレメン)             parser.parseColon() ||
2753b06bc7c6SValentin Clement (バレンタイン クレメン)             parser.parseAttribute(gangDimAttrs.emplace_back()))
2754b06bc7c6SValentin Clement (バレンタイン クレメン)           return failure();
2755b06bc7c6SValentin Clement (バレンタイン クレメン)         if (succeeded(parser.parseOptionalLSquare())) {
2756b06bc7c6SValentin Clement (バレンタイン クレメン)           if (parser.parseAttribute(gangDimDeviceTypeAttrs.emplace_back()) ||
2757b06bc7c6SValentin Clement (バレンタイン クレメン)               parser.parseRSquare())
2758b06bc7c6SValentin Clement (バレンタイン クレメン)             return failure();
2759b06bc7c6SValentin Clement (バレンタイン クレメン)         } else {
2760b06bc7c6SValentin Clement (バレンタイン クレメン)           gangDimDeviceTypeAttrs.push_back(mlir::acc::DeviceTypeAttr::get(
2761b06bc7c6SValentin Clement (バレンタイン クレメン)               parser.getContext(), mlir::acc::DeviceType::None));
2762b06bc7c6SValentin Clement (バレンタイン クレメン)         }
2763b06bc7c6SValentin Clement (バレンタイン クレメン)         return success();
2764b06bc7c6SValentin Clement (バレンタイン クレメン)       })))
2765b06bc7c6SValentin Clement (バレンタイン クレメン)     return failure();
276652a0b6a6SRazvan Lupusoru 
276752a0b6a6SRazvan Lupusoru   if (failed(parser.parseRParen()))
276852a0b6a6SRazvan Lupusoru     return failure();
2769b06bc7c6SValentin Clement (バレンタイン クレメン) 
2770b06bc7c6SValentin Clement (バレンタイン クレメン)   gang = ArrayAttr::get(parser.getContext(), gangAttrs);
2771b06bc7c6SValentin Clement (バレンタイン クレメン)   gangDim = ArrayAttr::get(parser.getContext(), gangDimAttrs);
2772b06bc7c6SValentin Clement (バレンタイン クレメン)   gangDimDeviceTypes =
2773b06bc7c6SValentin Clement (バレンタイン クレメン)       ArrayAttr::get(parser.getContext(), gangDimDeviceTypeAttrs);
277452a0b6a6SRazvan Lupusoru 
277552a0b6a6SRazvan Lupusoru   return success();
277652a0b6a6SRazvan Lupusoru }
277752a0b6a6SRazvan Lupusoru 
2778b06bc7c6SValentin Clement (バレンタイン クレメン) void printRoutineGangClause(OpAsmPrinter &p, Operation *op,
2779b06bc7c6SValentin Clement (バレンタイン クレメン)                             std::optional<mlir::ArrayAttr> gang,
2780b06bc7c6SValentin Clement (バレンタイン クレメン)                             std::optional<mlir::ArrayAttr> gangDim,
2781b06bc7c6SValentin Clement (バレンタイン クレメン)                             std::optional<mlir::ArrayAttr> gangDimDeviceTypes) {
2782b06bc7c6SValentin Clement (バレンタイン クレメン) 
2783b06bc7c6SValentin Clement (バレンタイン クレメン)   if (!hasDeviceTypeValues(gangDimDeviceTypes) && hasDeviceTypeValues(gang) &&
2784b06bc7c6SValentin Clement (バレンタイン クレメン)       gang->size() == 1) {
2785b06bc7c6SValentin Clement (バレンタイン クレメン)     auto deviceTypeAttr = mlir::dyn_cast<mlir::acc::DeviceTypeAttr>((*gang)[0]);
2786b06bc7c6SValentin Clement (バレンタイン クレメン)     if (deviceTypeAttr.getValue() == mlir::acc::DeviceType::None)
2787b06bc7c6SValentin Clement (バレンタイン クレメン)       return;
2788b06bc7c6SValentin Clement (バレンタイン クレメン)   }
2789b06bc7c6SValentin Clement (バレンタイン クレメン) 
2790b06bc7c6SValentin Clement (バレンタイン クレメン)   p << "(";
2791b06bc7c6SValentin Clement (バレンタイン クレメン) 
2792b06bc7c6SValentin Clement (バレンタイン クレメン)   printDeviceTypes(p, gang);
2793b06bc7c6SValentin Clement (バレンタイン クレメン) 
2794b06bc7c6SValentin Clement (バレンタイン クレメン)   if (hasDeviceTypeValues(gang) && hasDeviceTypeValues(gangDimDeviceTypes))
2795b06bc7c6SValentin Clement (バレンタイン クレメン)     p << ", ";
2796b06bc7c6SValentin Clement (バレンタイン クレメン) 
2797b06bc7c6SValentin Clement (バレンタイン クレメン)   if (hasDeviceTypeValues(gangDimDeviceTypes))
2798b06bc7c6SValentin Clement (バレンタイン クレメン)     llvm::interleaveComma(llvm::zip(*gangDim, *gangDimDeviceTypes), p,
2799b06bc7c6SValentin Clement (バレンタイン クレメン)                           [&](const auto &pair) {
2800b06bc7c6SValentin Clement (バレンタイン クレメン)                             p << acc::RoutineOp::getGangDimKeyword() << ": ";
2801b06bc7c6SValentin Clement (バレンタイン クレメン)                             p << std::get<0>(pair);
2802b06bc7c6SValentin Clement (バレンタイン クレメン)                             printSingleDeviceType(p, std::get<1>(pair));
2803b06bc7c6SValentin Clement (バレンタイン クレメン)                           });
2804b06bc7c6SValentin Clement (バレンタイン クレメン) 
2805b06bc7c6SValentin Clement (バレンタイン クレメン)   p << ")";
2806b06bc7c6SValentin Clement (バレンタイン クレメン) }
2807b06bc7c6SValentin Clement (バレンタイン クレメン) 
2808b06bc7c6SValentin Clement (バレンタイン クレメン) static ParseResult parseDeviceTypeArrayAttr(OpAsmParser &parser,
2809b06bc7c6SValentin Clement (バレンタイン クレメン)                                             mlir::ArrayAttr &deviceTypes) {
2810b06bc7c6SValentin Clement (バレンタイン クレメン)   llvm::SmallVector<mlir::Attribute> attributes;
2811b06bc7c6SValentin Clement (バレンタイン クレメン)   // Keyword only
2812b06bc7c6SValentin Clement (バレンタイン クレメン)   if (failed(parser.parseOptionalLParen())) {
2813b06bc7c6SValentin Clement (バレンタイン クレメン)     attributes.push_back(mlir::acc::DeviceTypeAttr::get(
2814b06bc7c6SValentin Clement (バレンタイン クレメン)         parser.getContext(), mlir::acc::DeviceType::None));
2815b06bc7c6SValentin Clement (バレンタイン クレメン)     deviceTypes = ArrayAttr::get(parser.getContext(), attributes);
2816b06bc7c6SValentin Clement (バレンタイン クレメン)     return success();
2817b06bc7c6SValentin Clement (バレンタイン クレメン)   }
2818b06bc7c6SValentin Clement (バレンタイン クレメン) 
2819b06bc7c6SValentin Clement (バレンタイン クレメン)   // Parse device type attributes
2820b06bc7c6SValentin Clement (バレンタイン クレメン)   if (succeeded(parser.parseOptionalLSquare())) {
2821b06bc7c6SValentin Clement (バレンタイン クレメン)     if (failed(parser.parseCommaSeparatedList([&]() {
2822b06bc7c6SValentin Clement (バレンタイン クレメン)           if (parser.parseAttribute(attributes.emplace_back()))
2823b06bc7c6SValentin Clement (バレンタイン クレメン)             return failure();
2824b06bc7c6SValentin Clement (バレンタイン クレメン)           return success();
2825b06bc7c6SValentin Clement (バレンタイン クレメン)         })))
2826b06bc7c6SValentin Clement (バレンタイン クレメン)       return failure();
2827b06bc7c6SValentin Clement (バレンタイン クレメン)     if (parser.parseRSquare() || parser.parseRParen())
2828b06bc7c6SValentin Clement (バレンタイン クレメン)       return failure();
2829b06bc7c6SValentin Clement (バレンタイン クレメン)   }
2830b06bc7c6SValentin Clement (バレンタイン クレメン)   deviceTypes = ArrayAttr::get(parser.getContext(), attributes);
2831b06bc7c6SValentin Clement (バレンタイン クレメン)   return success();
2832b06bc7c6SValentin Clement (バレンタイン クレメン) }
2833b06bc7c6SValentin Clement (バレンタイン クレメン) 
2834b06bc7c6SValentin Clement (バレンタイン クレメン) static void
2835b06bc7c6SValentin Clement (バレンタイン クレメン) printDeviceTypeArrayAttr(mlir::OpAsmPrinter &p, mlir::Operation *op,
2836b06bc7c6SValentin Clement (バレンタイン クレメン)                          std::optional<mlir::ArrayAttr> deviceTypes) {
2837b06bc7c6SValentin Clement (バレンタイン クレメン) 
2838b06bc7c6SValentin Clement (バレンタイン クレメン)   if (hasDeviceTypeValues(deviceTypes) && deviceTypes->size() == 1) {
2839b06bc7c6SValentin Clement (バレンタイン クレメン)     auto deviceTypeAttr =
2840b06bc7c6SValentin Clement (バレンタイン クレメン)         mlir::dyn_cast<mlir::acc::DeviceTypeAttr>((*deviceTypes)[0]);
2841b06bc7c6SValentin Clement (バレンタイン クレメン)     if (deviceTypeAttr.getValue() == mlir::acc::DeviceType::None)
2842b06bc7c6SValentin Clement (バレンタイン クレメン)       return;
2843b06bc7c6SValentin Clement (バレンタイン クレメン)   }
2844b06bc7c6SValentin Clement (バレンタイン クレメン) 
2845b06bc7c6SValentin Clement (バレンタイン クレメン)   if (!hasDeviceTypeValues(deviceTypes))
2846b06bc7c6SValentin Clement (バレンタイン クレメン)     return;
2847b06bc7c6SValentin Clement (バレンタイン クレメン) 
2848b06bc7c6SValentin Clement (バレンタイン クレメン)   p << "([";
2849b06bc7c6SValentin Clement (バレンタイン クレメン)   llvm::interleaveComma(*deviceTypes, p, [&](mlir::Attribute attr) {
2850b06bc7c6SValentin Clement (バレンタイン クレメン)     auto dTypeAttr = mlir::dyn_cast<mlir::acc::DeviceTypeAttr>(attr);
2851b06bc7c6SValentin Clement (バレンタイン クレメン)     p << dTypeAttr;
2852b06bc7c6SValentin Clement (バレンタイン クレメン)   });
2853b06bc7c6SValentin Clement (バレンタイン クレメン)   p << "])";
2854b06bc7c6SValentin Clement (バレンタイン クレメン) }
2855b06bc7c6SValentin Clement (バレンタイン クレメン) 
2856b06bc7c6SValentin Clement (バレンタイン クレメン) bool RoutineOp::hasWorker() { return hasWorker(mlir::acc::DeviceType::None); }
2857b06bc7c6SValentin Clement (バレンタイン クレメン) 
2858b06bc7c6SValentin Clement (バレンタイン クレメン) bool RoutineOp::hasWorker(mlir::acc::DeviceType deviceType) {
2859b06bc7c6SValentin Clement (バレンタイン クレメン)   return hasDeviceType(getWorker(), deviceType);
2860b06bc7c6SValentin Clement (バレンタイン クレメン) }
2861b06bc7c6SValentin Clement (バレンタイン クレメン) 
2862b06bc7c6SValentin Clement (バレンタイン クレメン) bool RoutineOp::hasVector() { return hasVector(mlir::acc::DeviceType::None); }
2863b06bc7c6SValentin Clement (バレンタイン クレメン) 
2864b06bc7c6SValentin Clement (バレンタイン クレメン) bool RoutineOp::hasVector(mlir::acc::DeviceType deviceType) {
2865b06bc7c6SValentin Clement (バレンタイン クレメン)   return hasDeviceType(getVector(), deviceType);
2866b06bc7c6SValentin Clement (バレンタイン クレメン) }
2867b06bc7c6SValentin Clement (バレンタイン クレメン) 
2868b06bc7c6SValentin Clement (バレンタイン クレメン) bool RoutineOp::hasSeq() { return hasSeq(mlir::acc::DeviceType::None); }
2869b06bc7c6SValentin Clement (バレンタイン クレメン) 
2870b06bc7c6SValentin Clement (バレンタイン クレメン) bool RoutineOp::hasSeq(mlir::acc::DeviceType deviceType) {
2871b06bc7c6SValentin Clement (バレンタイン クレメン)   return hasDeviceType(getSeq(), deviceType);
2872b06bc7c6SValentin Clement (バレンタイン クレメン) }
2873b06bc7c6SValentin Clement (バレンタイン クレメン) 
2874b06bc7c6SValentin Clement (バレンタイン クレメン) std::optional<llvm::StringRef> RoutineOp::getBindNameValue() {
2875b06bc7c6SValentin Clement (バレンタイン クレメン)   return getBindNameValue(mlir::acc::DeviceType::None);
2876b06bc7c6SValentin Clement (バレンタイン クレメン) }
2877b06bc7c6SValentin Clement (バレンタイン クレメン) 
2878b06bc7c6SValentin Clement (バレンタイン クレメン) std::optional<llvm::StringRef>
2879b06bc7c6SValentin Clement (バレンタイン クレメン) RoutineOp::getBindNameValue(mlir::acc::DeviceType deviceType) {
2880b06bc7c6SValentin Clement (バレンタイン クレメン)   if (!hasDeviceTypeValues(getBindNameDeviceType()))
2881b06bc7c6SValentin Clement (バレンタイン クレメン)     return std::nullopt;
2882b06bc7c6SValentin Clement (バレンタイン クレメン)   if (auto pos = findSegment(*getBindNameDeviceType(), deviceType)) {
2883b06bc7c6SValentin Clement (バレンタイン クレメン)     auto attr = (*getBindName())[*pos];
2884b06bc7c6SValentin Clement (バレンタイン クレメン)     auto stringAttr = dyn_cast<mlir::StringAttr>(attr);
2885b06bc7c6SValentin Clement (バレンタイン クレメン)     return stringAttr.getValue();
2886b06bc7c6SValentin Clement (バレンタイン クレメン)   }
2887b06bc7c6SValentin Clement (バレンタイン クレメン)   return std::nullopt;
2888b06bc7c6SValentin Clement (バレンタイン クレメン) }
2889b06bc7c6SValentin Clement (バレンタイン クレメン) 
2890b06bc7c6SValentin Clement (バレンタイン クレメン) bool RoutineOp::hasGang() { return hasGang(mlir::acc::DeviceType::None); }
2891b06bc7c6SValentin Clement (バレンタイン クレメン) 
2892b06bc7c6SValentin Clement (バレンタイン クレメン) bool RoutineOp::hasGang(mlir::acc::DeviceType deviceType) {
2893b06bc7c6SValentin Clement (バレンタイン クレメン)   return hasDeviceType(getGang(), deviceType);
2894b06bc7c6SValentin Clement (バレンタイン クレメン) }
2895b06bc7c6SValentin Clement (バレンタイン クレメン) 
2896b06bc7c6SValentin Clement (バレンタイン クレメン) std::optional<int64_t> RoutineOp::getGangDimValue() {
2897b06bc7c6SValentin Clement (バレンタイン クレメン)   return getGangDimValue(mlir::acc::DeviceType::None);
2898b06bc7c6SValentin Clement (バレンタイン クレメン) }
2899b06bc7c6SValentin Clement (バレンタイン クレメン) 
2900b06bc7c6SValentin Clement (バレンタイン クレメン) std::optional<int64_t>
2901b06bc7c6SValentin Clement (バレンタイン クレメン) RoutineOp::getGangDimValue(mlir::acc::DeviceType deviceType) {
2902b06bc7c6SValentin Clement (バレンタイン クレメン)   if (!hasDeviceTypeValues(getGangDimDeviceType()))
2903b06bc7c6SValentin Clement (バレンタイン クレメン)     return std::nullopt;
2904b06bc7c6SValentin Clement (バレンタイン クレメン)   if (auto pos = findSegment(*getGangDimDeviceType(), deviceType)) {
2905b06bc7c6SValentin Clement (バレンタイン クレメン)     auto intAttr = mlir::dyn_cast<mlir::IntegerAttr>((*getGangDim())[*pos]);
2906b06bc7c6SValentin Clement (バレンタイン クレメン)     return intAttr.getInt();
2907b06bc7c6SValentin Clement (バレンタイン クレメン)   }
2908b06bc7c6SValentin Clement (バレンタイン クレメン)   return std::nullopt;
290952a0b6a6SRazvan Lupusoru }
291052a0b6a6SRazvan Lupusoru 
291152a0b6a6SRazvan Lupusoru //===----------------------------------------------------------------------===//
291251323fe2SValentin Clement // InitOp
291351323fe2SValentin Clement //===----------------------------------------------------------------------===//
291451323fe2SValentin Clement 
2915ef72cf44SRiver Riddle LogicalResult acc::InitOp::verify() {
2916ef72cf44SRiver Riddle   Operation *currOp = *this;
2917ef72cf44SRiver Riddle   while ((currOp = currOp->getParentOp()))
29189c77350bSValentin Clement     if (isComputeOperation(currOp))
2919ef72cf44SRiver Riddle       return emitOpError("cannot be nested in a compute operation");
292051323fe2SValentin Clement   return success();
292151323fe2SValentin Clement }
292251323fe2SValentin Clement 
292351323fe2SValentin Clement //===----------------------------------------------------------------------===//
29249c77350bSValentin Clement // ShutdownOp
29259c77350bSValentin Clement //===----------------------------------------------------------------------===//
29269c77350bSValentin Clement 
2927ef72cf44SRiver Riddle LogicalResult acc::ShutdownOp::verify() {
2928ef72cf44SRiver Riddle   Operation *currOp = *this;
2929ef72cf44SRiver Riddle   while ((currOp = currOp->getParentOp()))
29309c77350bSValentin Clement     if (isComputeOperation(currOp))
2931ef72cf44SRiver Riddle       return emitOpError("cannot be nested in a compute operation");
29329c77350bSValentin Clement   return success();
29339c77350bSValentin Clement }
29349c77350bSValentin Clement 
29359c77350bSValentin Clement //===----------------------------------------------------------------------===//
29364bac6ed4SValentin Clement // SetOp
29374bac6ed4SValentin Clement //===----------------------------------------------------------------------===//
29384bac6ed4SValentin Clement 
29394bac6ed4SValentin Clement LogicalResult acc::SetOp::verify() {
29404bac6ed4SValentin Clement   Operation *currOp = *this;
29414bac6ed4SValentin Clement   while ((currOp = currOp->getParentOp()))
29424bac6ed4SValentin Clement     if (isComputeOperation(currOp))
29434bac6ed4SValentin Clement       return emitOpError("cannot be nested in a compute operation");
2944f706837eSValentin Clement (バレンタイン クレメン)   if (!getDeviceTypeAttr() && !getDefaultAsync() && !getDeviceNum())
29454bac6ed4SValentin Clement     return emitOpError("at least one default_async, device_num, or device_type "
29464bac6ed4SValentin Clement                        "operand must appear");
29474bac6ed4SValentin Clement   return success();
29484bac6ed4SValentin Clement }
29494bac6ed4SValentin Clement 
29504bac6ed4SValentin Clement //===----------------------------------------------------------------------===//
2951ecc99780SValentin Clement // UpdateOp
2952ecc99780SValentin Clement //===----------------------------------------------------------------------===//
2953ecc99780SValentin Clement 
2954ef72cf44SRiver Riddle LogicalResult acc::UpdateOp::verify() {
2955ecc99780SValentin Clement   // At least one of host or device should have a value.
2956689afa88SValentin Clement   if (getDataClauseOperands().empty())
2957689afa88SValentin Clement     return emitError("at least one value must be present in dataOperands");
2958ecc99780SValentin Clement 
295978ef0328SValentin Clement (バレンタイン クレメン)   if (failed(verifyDeviceTypeCountMatch(*this, getAsyncOperands(),
296078ef0328SValentin Clement (バレンタイン クレメン)                                         getAsyncOperandsDeviceTypeAttr(),
296178ef0328SValentin Clement (バレンタイン クレメン)                                         "async")))
296278ef0328SValentin Clement (バレンタイン クレメン)     return failure();
296378ef0328SValentin Clement (バレンタイン クレメン) 
296478ef0328SValentin Clement (バレンタイン クレメン)   if (failed(verifyDeviceTypeAndSegmentCountMatch(
296578ef0328SValentin Clement (バレンタイン クレメン)           *this, getWaitOperands(), getWaitOperandsSegmentsAttr(),
296678ef0328SValentin Clement (バレンタイン クレメン)           getWaitOperandsDeviceTypeAttr(), "wait")))
296778ef0328SValentin Clement (バレンタイン クレメン)     return failure();
296878ef0328SValentin Clement (バレンタイン クレメン) 
2969c09dc2d9SValentin Clement (バレンタイン クレメン)   if (failed(checkWaitAndAsyncConflict<acc::UpdateOp>(*this)))
2970c09dc2d9SValentin Clement (バレンタイン クレメン)     return failure();
2971bbb5dc49SValentin Clement 
297278a09cbdSValentin Clement   for (mlir::Value operand : getDataClauseOperands())
297378a09cbdSValentin Clement     if (!mlir::isa<acc::UpdateDeviceOp, acc::UpdateHostOp, acc::GetDevicePtrOp>(
297478a09cbdSValentin Clement             operand.getDefiningOp()))
297578a09cbdSValentin Clement       return emitError("expect data entry/exit operation or acc.getdeviceptr "
297678a09cbdSValentin Clement                        "as defining op");
297778a09cbdSValentin Clement 
2978bbb5dc49SValentin Clement   return success();
2979bbb5dc49SValentin Clement }
2980bbb5dc49SValentin Clement 
29816110b667SValentin Clement unsigned UpdateOp::getNumDataOperands() {
2982689afa88SValentin Clement   return getDataClauseOperands().size();
29836110b667SValentin Clement }
29846110b667SValentin Clement 
29856110b667SValentin Clement Value UpdateOp::getDataOperand(unsigned i) {
298678ef0328SValentin Clement (バレンタイン クレメン)   unsigned numOptional = getAsyncOperands().size();
2987f9806b3eSRiver Riddle   numOptional += getIfCond() ? 1 : 0;
2988f706837eSValentin Clement (バレンタイン クレメン)   return getOperand(getWaitOperands().size() + numOptional + i);
29896110b667SValentin Clement }
29906110b667SValentin Clement 
2991aa4e6a60SValentin Clement void UpdateOp::getCanonicalizationPatterns(RewritePatternSet &results,
2992aa4e6a60SValentin Clement                                            MLIRContext *context) {
2993aa4e6a60SValentin Clement   results.add<RemoveConstantIfCondition<UpdateOp>>(context);
2994aa4e6a60SValentin Clement }
2995aa4e6a60SValentin Clement 
299678ef0328SValentin Clement (バレンタイン クレメン) bool UpdateOp::hasAsyncOnly() {
299778ef0328SValentin Clement (バレンタイン クレメン)   return hasAsyncOnly(mlir::acc::DeviceType::None);
299878ef0328SValentin Clement (バレンタイン クレメン) }
299978ef0328SValentin Clement (バレンタイン クレメン) 
300078ef0328SValentin Clement (バレンタイン クレメン) bool UpdateOp::hasAsyncOnly(mlir::acc::DeviceType deviceType) {
300178ef0328SValentin Clement (バレンタイン クレメン)   return hasDeviceType(getAsync(), deviceType);
300278ef0328SValentin Clement (バレンタイン クレメン) }
300378ef0328SValentin Clement (バレンタイン クレメン) 
300478ef0328SValentin Clement (バレンタイン クレメン) mlir::Value UpdateOp::getAsyncValue() {
300578ef0328SValentin Clement (バレンタイン クレメン)   return getAsyncValue(mlir::acc::DeviceType::None);
300678ef0328SValentin Clement (バレンタイン クレメン) }
300778ef0328SValentin Clement (バレンタイン クレメン) 
300878ef0328SValentin Clement (バレンタイン クレメン) mlir::Value UpdateOp::getAsyncValue(mlir::acc::DeviceType deviceType) {
300978ef0328SValentin Clement (バレンタイン クレメン)   if (!hasDeviceTypeValues(getAsyncOperandsDeviceType()))
301078ef0328SValentin Clement (バレンタイン クレメン)     return {};
301178ef0328SValentin Clement (バレンタイン クレメン) 
301278ef0328SValentin Clement (バレンタイン クレメン)   if (auto pos = findSegment(*getAsyncOperandsDeviceType(), deviceType))
301378ef0328SValentin Clement (バレンタイン クレメン)     return getAsyncOperands()[*pos];
301478ef0328SValentin Clement (バレンタイン クレメン) 
301578ef0328SValentin Clement (バレンタイン クレメン)   return {};
301678ef0328SValentin Clement (バレンタイン クレメン) }
301778ef0328SValentin Clement (バレンタイン クレメン) 
301878ef0328SValentin Clement (バレンタイン クレメン) bool UpdateOp::hasWaitOnly() {
301978ef0328SValentin Clement (バレンタイン クレメン)   return hasWaitOnly(mlir::acc::DeviceType::None);
302078ef0328SValentin Clement (バレンタイン クレメン) }
302178ef0328SValentin Clement (バレンタイン クレメン) 
302278ef0328SValentin Clement (バレンタイン クレメン) bool UpdateOp::hasWaitOnly(mlir::acc::DeviceType deviceType) {
3023c09dc2d9SValentin Clement (バレンタイン クレメン)   return hasDeviceType(getWaitOnly(), deviceType);
302478ef0328SValentin Clement (バレンタイン クレメン) }
302578ef0328SValentin Clement (バレンタイン クレメン) 
302678ef0328SValentin Clement (バレンタイン クレメン) mlir::Operation::operand_range UpdateOp::getWaitValues() {
302778ef0328SValentin Clement (バレンタイン クレメン)   return getWaitValues(mlir::acc::DeviceType::None);
302878ef0328SValentin Clement (バレンタイン クレメン) }
302978ef0328SValentin Clement (バレンタイン クレメン) 
303078ef0328SValentin Clement (バレンタイン クレメン) mlir::Operation::operand_range
303178ef0328SValentin Clement (バレンタイン クレメン) UpdateOp::getWaitValues(mlir::acc::DeviceType deviceType) {
3032c09dc2d9SValentin Clement (バレンタイン クレメン)   return getWaitValuesWithoutDevnum(
3033c09dc2d9SValentin Clement (バレンタイン クレメン)       getWaitOperandsDeviceType(), getWaitOperands(), getWaitOperandsSegments(),
3034c09dc2d9SValentin Clement (バレンタイン クレメン)       getHasWaitDevnum(), deviceType);
3035c09dc2d9SValentin Clement (バレンタイン クレメン) }
3036c09dc2d9SValentin Clement (バレンタイン クレメン) 
3037c09dc2d9SValentin Clement (バレンタイン クレメン) mlir::Value UpdateOp::getWaitDevnum() {
3038c09dc2d9SValentin Clement (バレンタイン クレメン)   return getWaitDevnum(mlir::acc::DeviceType::None);
3039c09dc2d9SValentin Clement (バレンタイン クレメン) }
3040c09dc2d9SValentin Clement (バレンタイン クレメン) 
3041c09dc2d9SValentin Clement (バレンタイン クレメン) mlir::Value UpdateOp::getWaitDevnum(mlir::acc::DeviceType deviceType) {
3042c09dc2d9SValentin Clement (バレンタイン クレメン)   return getWaitDevnumValue(getWaitOperandsDeviceType(), getWaitOperands(),
3043c09dc2d9SValentin Clement (バレンタイン クレメン)                             getWaitOperandsSegments(), getHasWaitDevnum(),
3044c09dc2d9SValentin Clement (バレンタイン クレメン)                             deviceType);
304578ef0328SValentin Clement (バレンタイン クレメン) }
304678ef0328SValentin Clement (バレンタイン クレメン) 
3047cc3b8e73SValentin Clement //===----------------------------------------------------------------------===//
3048cc3b8e73SValentin Clement // WaitOp
3049cc3b8e73SValentin Clement //===----------------------------------------------------------------------===//
3050cc3b8e73SValentin Clement 
3051ef72cf44SRiver Riddle LogicalResult acc::WaitOp::verify() {
3052cc3b8e73SValentin Clement   // The async attribute represent the async clause without value. Therefore the
3053cc3b8e73SValentin Clement   // attribute and operand cannot appear at the same time.
3054f9806b3eSRiver Riddle   if (getAsyncOperand() && getAsync())
3055ef72cf44SRiver Riddle     return emitError("async attribute cannot appear with asyncOperand");
3056cc3b8e73SValentin Clement 
3057f9806b3eSRiver Riddle   if (getWaitDevnum() && getWaitOperands().empty())
3058ef72cf44SRiver Riddle     return emitError("wait_devnum cannot appear without waitOperands");
3059cc3b8e73SValentin Clement 
3060cc3b8e73SValentin Clement   return success();
3061cc3b8e73SValentin Clement }
3062cc3b8e73SValentin Clement 
30634225e7faSValentin Clement #define GET_OP_CLASSES
30644225e7faSValentin Clement #include "mlir/Dialect/OpenACC/OpenACCOps.cpp.inc"
3065aae51255SMogball 
3066aae51255SMogball #define GET_ATTRDEF_CLASSES
3067aae51255SMogball #include "mlir/Dialect/OpenACC/OpenACCOpsAttributes.cpp.inc"
3068c184dcb4SRazvan Lupusoru 
3069c184dcb4SRazvan Lupusoru #define GET_TYPEDEF_CLASSES
3070c184dcb4SRazvan Lupusoru #include "mlir/Dialect/OpenACC/OpenACCOpsTypes.cpp.inc"
3071132c376aSRazvan Lupusoru 
3072132c376aSRazvan Lupusoru //===----------------------------------------------------------------------===//
3073132c376aSRazvan Lupusoru // acc dialect utilities
3074132c376aSRazvan Lupusoru //===----------------------------------------------------------------------===//
3075132c376aSRazvan Lupusoru 
3076*cbcb7ad3SRazvan Lupusoru mlir::TypedValue<mlir::acc::PointerLikeType>
3077*cbcb7ad3SRazvan Lupusoru mlir::acc::getVarPtr(mlir::Operation *accDataClauseOp) {
3078*cbcb7ad3SRazvan Lupusoru   auto varPtr{llvm::TypeSwitch<mlir::Operation *,
3079*cbcb7ad3SRazvan Lupusoru                                mlir::TypedValue<mlir::acc::PointerLikeType>>(
3080*cbcb7ad3SRazvan Lupusoru                   accDataClauseOp)
3081132c376aSRazvan Lupusoru                   .Case<ACC_DATA_ENTRY_OPS>(
3082132c376aSRazvan Lupusoru                       [&](auto entry) { return entry.getVarPtr(); })
3083a711b042SRazvan Lupusoru                   .Case<mlir::acc::CopyoutOp, mlir::acc::UpdateHostOp>(
3084a711b042SRazvan Lupusoru                       [&](auto exit) { return exit.getVarPtr(); })
3085*cbcb7ad3SRazvan Lupusoru                   .Default([&](mlir::Operation *) {
3086*cbcb7ad3SRazvan Lupusoru                     return mlir::TypedValue<mlir::acc::PointerLikeType>();
3087*cbcb7ad3SRazvan Lupusoru                   })};
3088*cbcb7ad3SRazvan Lupusoru   return varPtr;
3089*cbcb7ad3SRazvan Lupusoru }
3090*cbcb7ad3SRazvan Lupusoru 
3091*cbcb7ad3SRazvan Lupusoru mlir::Value mlir::acc::getVar(mlir::Operation *accDataClauseOp) {
3092*cbcb7ad3SRazvan Lupusoru   auto varPtr{
3093*cbcb7ad3SRazvan Lupusoru       llvm::TypeSwitch<mlir::Operation *, mlir::Value>(accDataClauseOp)
3094*cbcb7ad3SRazvan Lupusoru           .Case<ACC_DATA_ENTRY_OPS>([&](auto entry) { return entry.getVar(); })
3095132c376aSRazvan Lupusoru           .Default([&](mlir::Operation *) { return mlir::Value(); })};
3096132c376aSRazvan Lupusoru   return varPtr;
3097132c376aSRazvan Lupusoru }
3098132c376aSRazvan Lupusoru 
3099*cbcb7ad3SRazvan Lupusoru mlir::Type mlir::acc::getVarType(mlir::Operation *accDataClauseOp) {
3100*cbcb7ad3SRazvan Lupusoru   auto varType{llvm::TypeSwitch<mlir::Operation *, mlir::Type>(accDataClauseOp)
3101*cbcb7ad3SRazvan Lupusoru                    .Case<ACC_DATA_ENTRY_OPS>(
3102*cbcb7ad3SRazvan Lupusoru                        [&](auto entry) { return entry.getVarType(); })
3103*cbcb7ad3SRazvan Lupusoru                    .Case<mlir::acc::CopyoutOp, mlir::acc::UpdateHostOp>(
3104*cbcb7ad3SRazvan Lupusoru                        [&](auto exit) { return exit.getVarType(); })
3105*cbcb7ad3SRazvan Lupusoru                    .Default([&](mlir::Operation *) { return mlir::Type(); })};
3106*cbcb7ad3SRazvan Lupusoru   return varType;
3107*cbcb7ad3SRazvan Lupusoru }
3108*cbcb7ad3SRazvan Lupusoru 
3109*cbcb7ad3SRazvan Lupusoru mlir::TypedValue<mlir::acc::PointerLikeType>
3110*cbcb7ad3SRazvan Lupusoru mlir::acc::getAccPtr(mlir::Operation *accDataClauseOp) {
3111*cbcb7ad3SRazvan Lupusoru   auto accPtr{llvm::TypeSwitch<mlir::Operation *,
3112*cbcb7ad3SRazvan Lupusoru                                mlir::TypedValue<mlir::acc::PointerLikeType>>(
3113*cbcb7ad3SRazvan Lupusoru                   accDataClauseOp)
3114a711b042SRazvan Lupusoru                   .Case<ACC_DATA_ENTRY_OPS, ACC_DATA_EXIT_OPS>(
3115a711b042SRazvan Lupusoru                       [&](auto dataClause) { return dataClause.getAccPtr(); })
3116*cbcb7ad3SRazvan Lupusoru                   .Default([&](mlir::Operation *) {
3117*cbcb7ad3SRazvan Lupusoru                     return mlir::TypedValue<mlir::acc::PointerLikeType>();
3118*cbcb7ad3SRazvan Lupusoru                   })};
3119*cbcb7ad3SRazvan Lupusoru   return accPtr;
3120*cbcb7ad3SRazvan Lupusoru }
3121*cbcb7ad3SRazvan Lupusoru 
3122*cbcb7ad3SRazvan Lupusoru mlir::Value mlir::acc::getAccVar(mlir::Operation *accDataClauseOp) {
3123*cbcb7ad3SRazvan Lupusoru   auto accPtr{llvm::TypeSwitch<mlir::Operation *, mlir::Value>(accDataClauseOp)
3124*cbcb7ad3SRazvan Lupusoru                   .Case<ACC_DATA_ENTRY_OPS, ACC_DATA_EXIT_OPS>(
3125*cbcb7ad3SRazvan Lupusoru                       [&](auto dataClause) { return dataClause.getAccVar(); })
3126a711b042SRazvan Lupusoru                   .Default([&](mlir::Operation *) { return mlir::Value(); })};
3127a711b042SRazvan Lupusoru   return accPtr;
3128a711b042SRazvan Lupusoru }
3129a711b042SRazvan Lupusoru 
3130a711b042SRazvan Lupusoru mlir::Value mlir::acc::getVarPtrPtr(mlir::Operation *accDataClauseOp) {
3131a711b042SRazvan Lupusoru   auto varPtrPtr{
3132a711b042SRazvan Lupusoru       llvm::TypeSwitch<mlir::Operation *, mlir::Value>(accDataClauseOp)
3133a711b042SRazvan Lupusoru           .Case<ACC_DATA_ENTRY_OPS>(
3134a711b042SRazvan Lupusoru               [&](auto dataClause) { return dataClause.getVarPtrPtr(); })
3135a711b042SRazvan Lupusoru           .Default([&](mlir::Operation *) { return mlir::Value(); })};
3136a711b042SRazvan Lupusoru   return varPtrPtr;
3137a711b042SRazvan Lupusoru }
3138a711b042SRazvan Lupusoru 
3139a711b042SRazvan Lupusoru mlir::SmallVector<mlir::Value>
3140a711b042SRazvan Lupusoru mlir::acc::getBounds(mlir::Operation *accDataClauseOp) {
3141a711b042SRazvan Lupusoru   mlir::SmallVector<mlir::Value> bounds{
3142a711b042SRazvan Lupusoru       llvm::TypeSwitch<mlir::Operation *, mlir::SmallVector<mlir::Value>>(
3143a711b042SRazvan Lupusoru           accDataClauseOp)
3144a711b042SRazvan Lupusoru           .Case<ACC_DATA_ENTRY_OPS, ACC_DATA_EXIT_OPS>([&](auto dataClause) {
3145a711b042SRazvan Lupusoru             return mlir::SmallVector<mlir::Value>(
3146a711b042SRazvan Lupusoru                 dataClause.getBounds().begin(), dataClause.getBounds().end());
3147a711b042SRazvan Lupusoru           })
3148a711b042SRazvan Lupusoru           .Default([&](mlir::Operation *) {
3149a711b042SRazvan Lupusoru             return mlir::SmallVector<mlir::Value, 0>();
3150a711b042SRazvan Lupusoru           })};
3151a711b042SRazvan Lupusoru   return bounds;
3152a711b042SRazvan Lupusoru }
3153a711b042SRazvan Lupusoru 
315440278bb1SSlava Zakharin mlir::SmallVector<mlir::Value>
315540278bb1SSlava Zakharin mlir::acc::getAsyncOperands(mlir::Operation *accDataClauseOp) {
315640278bb1SSlava Zakharin   return llvm::TypeSwitch<mlir::Operation *, mlir::SmallVector<mlir::Value>>(
315740278bb1SSlava Zakharin              accDataClauseOp)
315840278bb1SSlava Zakharin       .Case<ACC_DATA_ENTRY_OPS, ACC_DATA_EXIT_OPS>([&](auto dataClause) {
315940278bb1SSlava Zakharin         return mlir::SmallVector<mlir::Value>(
316040278bb1SSlava Zakharin             dataClause.getAsyncOperands().begin(),
316140278bb1SSlava Zakharin             dataClause.getAsyncOperands().end());
316240278bb1SSlava Zakharin       })
316340278bb1SSlava Zakharin       .Default([&](mlir::Operation *) {
316440278bb1SSlava Zakharin         return mlir::SmallVector<mlir::Value, 0>();
316540278bb1SSlava Zakharin       });
316640278bb1SSlava Zakharin }
316740278bb1SSlava Zakharin 
316840278bb1SSlava Zakharin mlir::ArrayAttr
316940278bb1SSlava Zakharin mlir::acc::getAsyncOperandsDeviceType(mlir::Operation *accDataClauseOp) {
317040278bb1SSlava Zakharin   return llvm::TypeSwitch<mlir::Operation *, mlir::ArrayAttr>(accDataClauseOp)
317140278bb1SSlava Zakharin       .Case<ACC_DATA_ENTRY_OPS, ACC_DATA_EXIT_OPS>([&](auto dataClause) {
317240278bb1SSlava Zakharin         return dataClause.getAsyncOperandsDeviceTypeAttr();
317340278bb1SSlava Zakharin       })
317440278bb1SSlava Zakharin       .Default([&](mlir::Operation *) { return mlir::ArrayAttr{}; });
317540278bb1SSlava Zakharin }
317640278bb1SSlava Zakharin 
317740278bb1SSlava Zakharin mlir::ArrayAttr mlir::acc::getAsyncOnly(mlir::Operation *accDataClauseOp) {
317840278bb1SSlava Zakharin   return llvm::TypeSwitch<mlir::Operation *, mlir::ArrayAttr>(accDataClauseOp)
317940278bb1SSlava Zakharin       .Case<ACC_DATA_ENTRY_OPS, ACC_DATA_EXIT_OPS>(
318040278bb1SSlava Zakharin           [&](auto dataClause) { return dataClause.getAsyncOnlyAttr(); })
318140278bb1SSlava Zakharin       .Default([&](mlir::Operation *) { return mlir::ArrayAttr{}; });
318240278bb1SSlava Zakharin }
318340278bb1SSlava Zakharin 
3184a711b042SRazvan Lupusoru std::optional<llvm::StringRef> mlir::acc::getVarName(mlir::Operation *accOp) {
3185a711b042SRazvan Lupusoru   auto name{
3186a711b042SRazvan Lupusoru       llvm::TypeSwitch<mlir::Operation *, std::optional<llvm::StringRef>>(accOp)
3187a711b042SRazvan Lupusoru           .Case<ACC_DATA_ENTRY_OPS>([&](auto entry) { return entry.getName(); })
3188a711b042SRazvan Lupusoru           .Default([&](mlir::Operation *) -> std::optional<llvm::StringRef> {
3189a711b042SRazvan Lupusoru             return {};
3190a711b042SRazvan Lupusoru           })};
3191a711b042SRazvan Lupusoru   return name;
3192a711b042SRazvan Lupusoru }
3193a711b042SRazvan Lupusoru 
3194132c376aSRazvan Lupusoru std::optional<mlir::acc::DataClause>
3195132c376aSRazvan Lupusoru mlir::acc::getDataClause(mlir::Operation *accDataEntryOp) {
3196132c376aSRazvan Lupusoru   auto dataClause{
3197132c376aSRazvan Lupusoru       llvm::TypeSwitch<mlir::Operation *, std::optional<mlir::acc::DataClause>>(
3198132c376aSRazvan Lupusoru           accDataEntryOp)
3199132c376aSRazvan Lupusoru           .Case<ACC_DATA_ENTRY_OPS>(
3200132c376aSRazvan Lupusoru               [&](auto entry) { return entry.getDataClause(); })
3201132c376aSRazvan Lupusoru           .Default([&](mlir::Operation *) { return std::nullopt; })};
3202132c376aSRazvan Lupusoru   return dataClause;
3203132c376aSRazvan Lupusoru }
32044bdc9057SRazvan Lupusoru 
32054bdc9057SRazvan Lupusoru bool mlir::acc::getImplicitFlag(mlir::Operation *accDataEntryOp) {
32064bdc9057SRazvan Lupusoru   auto implicit{llvm::TypeSwitch<mlir::Operation *, bool>(accDataEntryOp)
32074bdc9057SRazvan Lupusoru                     .Case<ACC_DATA_ENTRY_OPS>(
32084bdc9057SRazvan Lupusoru                         [&](auto entry) { return entry.getImplicit(); })
32094bdc9057SRazvan Lupusoru                     .Default([&](mlir::Operation *) { return false; })};
32104bdc9057SRazvan Lupusoru   return implicit;
32114bdc9057SRazvan Lupusoru }
3212a711b042SRazvan Lupusoru 
3213a711b042SRazvan Lupusoru mlir::ValueRange mlir::acc::getDataOperands(mlir::Operation *accOp) {
3214a711b042SRazvan Lupusoru   auto dataOperands{
3215a711b042SRazvan Lupusoru       llvm::TypeSwitch<mlir::Operation *, mlir::ValueRange>(accOp)
3216a711b042SRazvan Lupusoru           .Case<ACC_COMPUTE_AND_DATA_CONSTRUCT_OPS>(
3217a711b042SRazvan Lupusoru               [&](auto entry) { return entry.getDataClauseOperands(); })
3218a711b042SRazvan Lupusoru           .Default([&](mlir::Operation *) { return mlir::ValueRange(); })};
3219a711b042SRazvan Lupusoru   return dataOperands;
3220a711b042SRazvan Lupusoru }
3221a711b042SRazvan Lupusoru 
3222a711b042SRazvan Lupusoru mlir::MutableOperandRange
3223a711b042SRazvan Lupusoru mlir::acc::getMutableDataOperands(mlir::Operation *accOp) {
3224a711b042SRazvan Lupusoru   auto dataOperands{
3225a711b042SRazvan Lupusoru       llvm::TypeSwitch<mlir::Operation *, mlir::MutableOperandRange>(accOp)
3226a711b042SRazvan Lupusoru           .Case<ACC_COMPUTE_AND_DATA_CONSTRUCT_OPS>(
3227a711b042SRazvan Lupusoru               [&](auto entry) { return entry.getDataClauseOperandsMutable(); })
3228a711b042SRazvan Lupusoru           .Default([&](mlir::Operation *) { return nullptr; })};
3229a711b042SRazvan Lupusoru   return dataOperands;
3230a711b042SRazvan Lupusoru }
3231