MLIR  20.0.0git
GroupOps.cpp
Go to the documentation of this file.
1 //===- GroupOps.cpp - MLIR SPIR-V Group Ops ------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Defines the group operations in the SPIR-V dialect.
10 //
11 //===----------------------------------------------------------------------===//
12 
15 
16 #include "SPIRVOpUtils.h"
17 #include "SPIRVParsingUtils.h"
18 
19 using namespace mlir::spirv::AttrNames;
20 
21 namespace mlir::spirv {
22 
23 template <typename OpTy>
24 static ParseResult parseGroupNonUniformArithmeticOp(OpAsmParser &parser,
25  OperationState &state) {
26  spirv::Scope executionScope;
27  GroupOperation groupOperation;
29  if (spirv::parseEnumStrAttr<spirv::ScopeAttr>(
30  executionScope, parser, state,
31  OpTy::getExecutionScopeAttrName(state.name)) ||
32  spirv::parseEnumStrAttr<GroupOperationAttr>(
33  groupOperation, parser, state,
34  OpTy::getGroupOperationAttrName(state.name)) ||
35  parser.parseOperand(valueInfo))
36  return failure();
37 
38  std::optional<OpAsmParser::UnresolvedOperand> clusterSizeInfo;
39  if (succeeded(parser.parseOptionalKeyword(kClusterSize))) {
40  clusterSizeInfo = OpAsmParser::UnresolvedOperand();
41  if (parser.parseLParen() || parser.parseOperand(*clusterSizeInfo) ||
42  parser.parseRParen())
43  return failure();
44  }
45 
46  Type resultType;
47  if (parser.parseColonType(resultType))
48  return failure();
49 
50  if (parser.resolveOperand(valueInfo, resultType, state.operands))
51  return failure();
52 
53  if (clusterSizeInfo) {
54  Type i32Type = parser.getBuilder().getIntegerType(32);
55  if (parser.resolveOperand(*clusterSizeInfo, i32Type, state.operands))
56  return failure();
57  }
58 
59  return parser.addTypeToList(resultType, state.types);
60 }
61 
62 template <typename GroupNonUniformArithmeticOpTy>
64  OpAsmPrinter &printer) {
65  printer
66  << " \""
67  << stringifyScope(
68  groupOp
69  ->getAttrOfType<spirv::ScopeAttr>(
70  GroupNonUniformArithmeticOpTy::getExecutionScopeAttrName(
71  groupOp->getName()))
72  .getValue())
73  << "\" \""
74  << stringifyGroupOperation(
75  groupOp
76  ->getAttrOfType<GroupOperationAttr>(
77  GroupNonUniformArithmeticOpTy::getGroupOperationAttrName(
78  groupOp->getName()))
79  .getValue())
80  << "\" " << groupOp->getOperand(0);
81 
82  if (groupOp->getNumOperands() > 1)
83  printer << " " << kClusterSize << '(' << groupOp->getOperand(1) << ')';
84  printer << " : " << groupOp->getResult(0).getType();
85 }
86 
87 template <typename OpTy>
88 static LogicalResult verifyGroupNonUniformArithmeticOp(Operation *groupOp) {
89  spirv::Scope scope =
90  groupOp
91  ->getAttrOfType<spirv::ScopeAttr>(
92  OpTy::getExecutionScopeAttrName(groupOp->getName()))
93  .getValue();
94  if (scope != spirv::Scope::Workgroup && scope != spirv::Scope::Subgroup)
95  return groupOp->emitOpError(
96  "execution scope must be 'Workgroup' or 'Subgroup'");
97 
98  GroupOperation operation =
99  groupOp
100  ->getAttrOfType<GroupOperationAttr>(
101  OpTy::getGroupOperationAttrName(groupOp->getName()))
102  .getValue();
103  if (operation == GroupOperation::ClusteredReduce &&
104  groupOp->getNumOperands() == 1)
105  return groupOp->emitOpError("cluster size operand must be provided for "
106  "'ClusteredReduce' group operation");
107  if (groupOp->getNumOperands() > 1) {
108  Operation *sizeOp = groupOp->getOperand(1).getDefiningOp();
109  int32_t clusterSize = 0;
110 
111  // TODO: support specialization constant here.
112  if (failed(extractValueFromConstOp(sizeOp, clusterSize)))
113  return groupOp->emitOpError(
114  "cluster size operand must come from a constant op");
115 
116  if (!llvm::isPowerOf2_32(clusterSize))
117  return groupOp->emitOpError(
118  "cluster size operand must be a power of two");
119  }
120  return success();
121 }
122 
123 //===----------------------------------------------------------------------===//
124 // spirv.GroupBroadcast
125 //===----------------------------------------------------------------------===//
126 
127 LogicalResult GroupBroadcastOp::verify() {
128  spirv::Scope scope = getExecutionScope();
129  if (scope != spirv::Scope::Workgroup && scope != spirv::Scope::Subgroup)
130  return emitOpError("execution scope must be 'Workgroup' or 'Subgroup'");
131 
132  if (auto localIdTy = llvm::dyn_cast<VectorType>(getLocalid().getType()))
133  if (localIdTy.getNumElements() != 2 && localIdTy.getNumElements() != 3)
134  return emitOpError("localid is a vector and can be with only "
135  " 2 or 3 components, actual number is ")
136  << localIdTy.getNumElements();
137 
138  return success();
139 }
140 
141 //===----------------------------------------------------------------------===//
142 // spirv.GroupNonUniformBallotOp
143 //===----------------------------------------------------------------------===//
144 
145 LogicalResult GroupNonUniformBallotOp::verify() {
146  spirv::Scope scope = getExecutionScope();
147  if (scope != spirv::Scope::Workgroup && scope != spirv::Scope::Subgroup)
148  return emitOpError("execution scope must be 'Workgroup' or 'Subgroup'");
149 
150  return success();
151 }
152 
153 //===----------------------------------------------------------------------===//
154 // spirv.GroupNonUniformBallotFindLSBOp
155 //===----------------------------------------------------------------------===//
156 
158  spirv::Scope scope = getExecutionScope();
159  if (scope != spirv::Scope::Workgroup && scope != spirv::Scope::Subgroup)
160  return emitOpError("execution scope must be 'Workgroup' or 'Subgroup'");
161 
162  return success();
163 }
164 
165 //===----------------------------------------------------------------------===//
166 // spirv.GroupNonUniformBallotFindLSBOp
167 //===----------------------------------------------------------------------===//
168 
170  spirv::Scope scope = getExecutionScope();
171  if (scope != spirv::Scope::Workgroup && scope != spirv::Scope::Subgroup)
172  return emitOpError("execution scope must be 'Workgroup' or 'Subgroup'");
173 
174  return success();
175 }
176 
177 //===----------------------------------------------------------------------===//
178 // spirv.GroupNonUniformBroadcast
179 //===----------------------------------------------------------------------===//
180 
181 LogicalResult GroupNonUniformBroadcastOp::verify() {
182  spirv::Scope scope = getExecutionScope();
183  if (scope != spirv::Scope::Workgroup && scope != spirv::Scope::Subgroup)
184  return emitOpError("execution scope must be 'Workgroup' or 'Subgroup'");
185 
186  // SPIR-V spec: "Before version 1.5, Id must come from a
187  // constant instruction.
188  auto targetEnv = spirv::getDefaultTargetEnv(getContext());
189  if (auto spirvModule = (*this)->getParentOfType<spirv::ModuleOp>())
190  targetEnv = spirv::lookupTargetEnvOrDefault(spirvModule);
191 
192  if (targetEnv.getVersion() < spirv::Version::V_1_5) {
193  auto *idOp = getId().getDefiningOp();
194  if (!idOp || !isa<spirv::ConstantOp, // for normal constant
195  spirv::ReferenceOfOp>(idOp)) // for spec constant
196  return emitOpError("id must be the result of a constant op");
197  }
198 
199  return success();
200 }
201 
202 //===----------------------------------------------------------------------===//
203 // spirv.GroupNonUniformShuffle*
204 //===----------------------------------------------------------------------===//
205 
206 template <typename OpTy>
207 static LogicalResult verifyGroupNonUniformShuffleOp(OpTy op) {
208  spirv::Scope scope = op.getExecutionScope();
209  if (scope != spirv::Scope::Workgroup && scope != spirv::Scope::Subgroup)
210  return op.emitOpError("execution scope must be 'Workgroup' or 'Subgroup'");
211 
212  if (op.getOperands().back().getType().isSignedInteger())
213  return op.emitOpError("second operand must be a singless/unsigned integer");
214 
215  return success();
216 }
217 
218 LogicalResult GroupNonUniformShuffleOp::verify() {
219  return verifyGroupNonUniformShuffleOp(*this);
220 }
221 LogicalResult GroupNonUniformShuffleDownOp::verify() {
222  return verifyGroupNonUniformShuffleOp(*this);
223 }
224 LogicalResult GroupNonUniformShuffleUpOp::verify() {
225  return verifyGroupNonUniformShuffleOp(*this);
226 }
227 LogicalResult GroupNonUniformShuffleXorOp::verify() {
228  return verifyGroupNonUniformShuffleOp(*this);
229 }
230 
231 //===----------------------------------------------------------------------===//
232 // spirv.GroupNonUniformElectOp
233 //===----------------------------------------------------------------------===//
234 
235 LogicalResult GroupNonUniformElectOp::verify() {
236  spirv::Scope scope = getExecutionScope();
237  if (scope != spirv::Scope::Workgroup && scope != spirv::Scope::Subgroup)
238  return emitOpError("execution scope must be 'Workgroup' or 'Subgroup'");
239 
240  return success();
241 }
242 
243 //===----------------------------------------------------------------------===//
244 // spirv.GroupNonUniformFAddOp
245 //===----------------------------------------------------------------------===//
246 
247 LogicalResult GroupNonUniformFAddOp::verify() {
248  return verifyGroupNonUniformArithmeticOp<GroupNonUniformFAddOp>(*this);
249 }
250 
251 ParseResult GroupNonUniformFAddOp::parse(OpAsmParser &parser,
252  OperationState &result) {
253  return parseGroupNonUniformArithmeticOp<GroupNonUniformFAddOp>(parser,
254  result);
255 }
256 
257 void GroupNonUniformFAddOp::print(OpAsmPrinter &p) {
258  printGroupNonUniformArithmeticOp<GroupNonUniformFAddOp>(*this, p);
259 }
260 
261 //===----------------------------------------------------------------------===//
262 // spirv.GroupNonUniformFMaxOp
263 //===----------------------------------------------------------------------===//
264 
265 LogicalResult GroupNonUniformFMaxOp::verify() {
266  return verifyGroupNonUniformArithmeticOp<GroupNonUniformFMaxOp>(*this);
267 }
268 
269 ParseResult GroupNonUniformFMaxOp::parse(OpAsmParser &parser,
270  OperationState &result) {
271  return parseGroupNonUniformArithmeticOp<GroupNonUniformFMaxOp>(parser,
272  result);
273 }
274 
275 void GroupNonUniformFMaxOp::print(OpAsmPrinter &p) {
276  printGroupNonUniformArithmeticOp<GroupNonUniformFMaxOp>(*this, p);
277 }
278 
279 //===----------------------------------------------------------------------===//
280 // spirv.GroupNonUniformFMinOp
281 //===----------------------------------------------------------------------===//
282 
283 LogicalResult GroupNonUniformFMinOp::verify() {
284  return verifyGroupNonUniformArithmeticOp<GroupNonUniformFMinOp>(*this);
285 }
286 
287 ParseResult GroupNonUniformFMinOp::parse(OpAsmParser &parser,
288  OperationState &result) {
289  return parseGroupNonUniformArithmeticOp<GroupNonUniformFMinOp>(parser,
290  result);
291 }
292 
293 void GroupNonUniformFMinOp::print(OpAsmPrinter &p) {
294  printGroupNonUniformArithmeticOp<GroupNonUniformFMinOp>(*this, p);
295 }
296 
297 //===----------------------------------------------------------------------===//
298 // spirv.GroupNonUniformFMulOp
299 //===----------------------------------------------------------------------===//
300 
301 LogicalResult GroupNonUniformFMulOp::verify() {
302  return verifyGroupNonUniformArithmeticOp<GroupNonUniformFMulOp>(*this);
303 }
304 
305 ParseResult GroupNonUniformFMulOp::parse(OpAsmParser &parser,
306  OperationState &result) {
307  return parseGroupNonUniformArithmeticOp<GroupNonUniformFMulOp>(parser,
308  result);
309 }
310 
311 void GroupNonUniformFMulOp::print(OpAsmPrinter &p) {
312  printGroupNonUniformArithmeticOp<GroupNonUniformFMulOp>(*this, p);
313 }
314 
315 //===----------------------------------------------------------------------===//
316 // spirv.GroupNonUniformIAddOp
317 //===----------------------------------------------------------------------===//
318 
319 LogicalResult GroupNonUniformIAddOp::verify() {
320  return verifyGroupNonUniformArithmeticOp<GroupNonUniformIAddOp>(*this);
321 }
322 
323 ParseResult GroupNonUniformIAddOp::parse(OpAsmParser &parser,
324  OperationState &result) {
325  return parseGroupNonUniformArithmeticOp<GroupNonUniformIAddOp>(parser,
326  result);
327 }
328 
329 void GroupNonUniformIAddOp::print(OpAsmPrinter &p) {
330  printGroupNonUniformArithmeticOp<GroupNonUniformIAddOp>(*this, p);
331 }
332 
333 //===----------------------------------------------------------------------===//
334 // spirv.GroupNonUniformIMulOp
335 //===----------------------------------------------------------------------===//
336 
337 LogicalResult GroupNonUniformIMulOp::verify() {
338  return verifyGroupNonUniformArithmeticOp<GroupNonUniformIMulOp>(*this);
339 }
340 
341 ParseResult GroupNonUniformIMulOp::parse(OpAsmParser &parser,
342  OperationState &result) {
343  return parseGroupNonUniformArithmeticOp<GroupNonUniformIMulOp>(parser,
344  result);
345 }
346 
347 void GroupNonUniformIMulOp::print(OpAsmPrinter &p) {
348  printGroupNonUniformArithmeticOp<GroupNonUniformIMulOp>(*this, p);
349 }
350 
351 //===----------------------------------------------------------------------===//
352 // spirv.GroupNonUniformSMaxOp
353 //===----------------------------------------------------------------------===//
354 
355 LogicalResult GroupNonUniformSMaxOp::verify() {
356  return verifyGroupNonUniformArithmeticOp<GroupNonUniformSMaxOp>(*this);
357 }
358 
359 ParseResult GroupNonUniformSMaxOp::parse(OpAsmParser &parser,
360  OperationState &result) {
361  return parseGroupNonUniformArithmeticOp<GroupNonUniformSMaxOp>(parser,
362  result);
363 }
364 
365 void GroupNonUniformSMaxOp::print(OpAsmPrinter &p) {
366  printGroupNonUniformArithmeticOp<GroupNonUniformSMaxOp>(*this, p);
367 }
368 
369 //===----------------------------------------------------------------------===//
370 // spirv.GroupNonUniformSMinOp
371 //===----------------------------------------------------------------------===//
372 
373 LogicalResult GroupNonUniformSMinOp::verify() {
374  return verifyGroupNonUniformArithmeticOp<GroupNonUniformSMinOp>(*this);
375 }
376 
377 ParseResult GroupNonUniformSMinOp::parse(OpAsmParser &parser,
378  OperationState &result) {
379  return parseGroupNonUniformArithmeticOp<GroupNonUniformSMinOp>(parser,
380  result);
381 }
382 
383 void GroupNonUniformSMinOp::print(OpAsmPrinter &p) {
384  printGroupNonUniformArithmeticOp<GroupNonUniformSMinOp>(*this, p);
385 }
386 
387 //===----------------------------------------------------------------------===//
388 // spirv.GroupNonUniformUMaxOp
389 //===----------------------------------------------------------------------===//
390 
391 LogicalResult GroupNonUniformUMaxOp::verify() {
392  return verifyGroupNonUniformArithmeticOp<GroupNonUniformUMaxOp>(*this);
393 }
394 
395 ParseResult GroupNonUniformUMaxOp::parse(OpAsmParser &parser,
396  OperationState &result) {
397  return parseGroupNonUniformArithmeticOp<GroupNonUniformUMaxOp>(parser,
398  result);
399 }
400 
401 void GroupNonUniformUMaxOp::print(OpAsmPrinter &p) {
402  printGroupNonUniformArithmeticOp<GroupNonUniformUMaxOp>(*this, p);
403 }
404 
405 //===----------------------------------------------------------------------===//
406 // spirv.GroupNonUniformUMinOp
407 //===----------------------------------------------------------------------===//
408 
409 LogicalResult GroupNonUniformUMinOp::verify() {
410  return verifyGroupNonUniformArithmeticOp<GroupNonUniformUMinOp>(*this);
411 }
412 
413 ParseResult GroupNonUniformUMinOp::parse(OpAsmParser &parser,
414  OperationState &result) {
415  return parseGroupNonUniformArithmeticOp<GroupNonUniformUMinOp>(parser,
416  result);
417 }
418 
419 void GroupNonUniformUMinOp::print(OpAsmPrinter &p) {
420  printGroupNonUniformArithmeticOp<GroupNonUniformUMinOp>(*this, p);
421 }
422 
423 //===----------------------------------------------------------------------===//
424 // spirv.GroupNonUniformBitwiseAnd
425 //===----------------------------------------------------------------------===//
426 
427 LogicalResult GroupNonUniformBitwiseAndOp::verify() {
428  return verifyGroupNonUniformArithmeticOp<GroupNonUniformBitwiseAndOp>(*this);
429 }
430 
431 ParseResult GroupNonUniformBitwiseAndOp::parse(OpAsmParser &parser,
432  OperationState &result) {
433  return parseGroupNonUniformArithmeticOp<GroupNonUniformBitwiseAndOp>(parser,
434  result);
435 }
436 
437 void GroupNonUniformBitwiseAndOp::print(OpAsmPrinter &p) {
438  printGroupNonUniformArithmeticOp<GroupNonUniformBitwiseAndOp>(*this, p);
439 }
440 
441 //===----------------------------------------------------------------------===//
442 // spirv.GroupNonUniformBitwiseOr
443 //===----------------------------------------------------------------------===//
444 
445 LogicalResult GroupNonUniformBitwiseOrOp::verify() {
446  return verifyGroupNonUniformArithmeticOp<GroupNonUniformBitwiseOrOp>(*this);
447 }
448 
449 ParseResult GroupNonUniformBitwiseOrOp::parse(OpAsmParser &parser,
450  OperationState &result) {
451  return parseGroupNonUniformArithmeticOp<GroupNonUniformBitwiseOrOp>(parser,
452  result);
453 }
454 
455 void GroupNonUniformBitwiseOrOp::print(OpAsmPrinter &p) {
456  printGroupNonUniformArithmeticOp<GroupNonUniformBitwiseOrOp>(*this, p);
457 }
458 
459 //===----------------------------------------------------------------------===//
460 // spirv.GroupNonUniformBitwiseXor
461 //===----------------------------------------------------------------------===//
462 
463 LogicalResult GroupNonUniformBitwiseXorOp::verify() {
464  return verifyGroupNonUniformArithmeticOp<GroupNonUniformBitwiseXorOp>(*this);
465 }
466 
467 ParseResult GroupNonUniformBitwiseXorOp::parse(OpAsmParser &parser,
468  OperationState &result) {
469  return parseGroupNonUniformArithmeticOp<GroupNonUniformBitwiseXorOp>(parser,
470  result);
471 }
472 
473 void GroupNonUniformBitwiseXorOp::print(OpAsmPrinter &p) {
474  printGroupNonUniformArithmeticOp<GroupNonUniformBitwiseXorOp>(*this, p);
475 }
476 
477 //===----------------------------------------------------------------------===//
478 // spirv.GroupNonUniformLogicalAnd
479 //===----------------------------------------------------------------------===//
480 
481 LogicalResult GroupNonUniformLogicalAndOp::verify() {
482  return verifyGroupNonUniformArithmeticOp<GroupNonUniformLogicalAndOp>(*this);
483 }
484 
485 ParseResult GroupNonUniformLogicalAndOp::parse(OpAsmParser &parser,
486  OperationState &result) {
487  return parseGroupNonUniformArithmeticOp<GroupNonUniformLogicalAndOp>(parser,
488  result);
489 }
490 
491 void GroupNonUniformLogicalAndOp::print(OpAsmPrinter &p) {
492  printGroupNonUniformArithmeticOp<GroupNonUniformLogicalAndOp>(*this, p);
493 }
494 
495 //===----------------------------------------------------------------------===//
496 // spirv.GroupNonUniformLogicalOr
497 //===----------------------------------------------------------------------===//
498 
499 LogicalResult GroupNonUniformLogicalOrOp::verify() {
500  return verifyGroupNonUniformArithmeticOp<GroupNonUniformLogicalOrOp>(*this);
501 }
502 
503 ParseResult GroupNonUniformLogicalOrOp::parse(OpAsmParser &parser,
504  OperationState &result) {
505  return parseGroupNonUniformArithmeticOp<GroupNonUniformLogicalOrOp>(parser,
506  result);
507 }
508 
509 void GroupNonUniformLogicalOrOp::print(OpAsmPrinter &p) {
510  printGroupNonUniformArithmeticOp<GroupNonUniformLogicalOrOp>(*this, p);
511 }
512 
513 //===----------------------------------------------------------------------===//
514 // spirv.GroupNonUniformLogicalXor
515 //===----------------------------------------------------------------------===//
516 
517 LogicalResult GroupNonUniformLogicalXorOp::verify() {
518  return verifyGroupNonUniformArithmeticOp<GroupNonUniformLogicalXorOp>(*this);
519 }
520 
521 ParseResult GroupNonUniformLogicalXorOp::parse(OpAsmParser &parser,
522  OperationState &result) {
523  return parseGroupNonUniformArithmeticOp<GroupNonUniformLogicalXorOp>(parser,
524  result);
525 }
526 
527 void GroupNonUniformLogicalXorOp::print(OpAsmPrinter &p) {
528  printGroupNonUniformArithmeticOp<GroupNonUniformLogicalXorOp>(*this, p);
529 }
530 
531 //===----------------------------------------------------------------------===//
532 // Group op verification
533 //===----------------------------------------------------------------------===//
534 
535 template <typename Op>
536 static LogicalResult verifyGroupOp(Op op) {
537  spirv::Scope scope = op.getExecutionScope();
538  if (scope != spirv::Scope::Workgroup && scope != spirv::Scope::Subgroup)
539  return op.emitOpError("execution scope must be 'Workgroup' or 'Subgroup'");
540 
541  return success();
542 }
543 
544 LogicalResult GroupIAddOp::verify() { return verifyGroupOp(*this); }
545 
546 LogicalResult GroupFAddOp::verify() { return verifyGroupOp(*this); }
547 
548 LogicalResult GroupFMinOp::verify() { return verifyGroupOp(*this); }
549 
550 LogicalResult GroupUMinOp::verify() { return verifyGroupOp(*this); }
551 
552 LogicalResult GroupSMinOp::verify() { return verifyGroupOp(*this); }
553 
554 LogicalResult GroupFMaxOp::verify() { return verifyGroupOp(*this); }
555 
556 LogicalResult GroupUMaxOp::verify() { return verifyGroupOp(*this); }
557 
558 LogicalResult GroupSMaxOp::verify() { return verifyGroupOp(*this); }
559 
560 LogicalResult GroupIMulKHROp::verify() { return verifyGroupOp(*this); }
561 
562 LogicalResult GroupFMulKHROp::verify() { return verifyGroupOp(*this); }
563 
564 } // namespace mlir::spirv
static MLIRContext * getContext(OpFoldResult val)
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
virtual Builder & getBuilder() const =0
Return a builder which provides useful access to MLIRContext, global objects like types and attribute...
virtual ParseResult parseOptionalKeyword(StringRef keyword)=0
Parse the given keyword if present.
virtual ParseResult parseRParen()=0
Parse a ) token.
ParseResult addTypeToList(Type type, SmallVectorImpl< Type > &result)
Add the specified type to the end of the specified type list and return success.
virtual ParseResult parseColonType(Type &result)=0
Parse a colon followed by a type.
virtual ParseResult parseLParen()=0
Parse a ( token.
IntegerType getIntegerType(unsigned width)
Definition: Builders.cpp:111
The OpAsmParser has methods for interacting with the asm parser: parsing things from it,...
virtual ParseResult resolveOperand(const UnresolvedOperand &operand, Type type, SmallVectorImpl< Value > &result)=0
Resolve an operand to an SSA value, emitting an error on failure.
virtual ParseResult parseOperand(UnresolvedOperand &result, bool allowResultNumber=true)=0
Parse a single SSA value operand name along with a result number if allowResultNumber is true.
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
This provides public APIs that all operations should have.
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
Value getOperand(unsigned idx)
Definition: Operation.h:345
AttrClass getAttrOfType(StringAttr name)
Definition: Operation.h:545
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
Definition: Operation.h:402
unsigned getNumOperands()
Definition: Operation.h:341
OperationName getName()
The name of an operation is the key identifier for it.
Definition: Operation.h:119
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
Definition: Operation.cpp:671
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
Type getType() const
Return the type of this value.
Definition: Value.h:129
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
Definition: Value.cpp:20
QueryRef parse(llvm::StringRef line, const QuerySession &qs)
Definition: Query.cpp:20
constexpr char kClusterSize[]
static LogicalResult verifyGroupNonUniformArithmeticOp(Operation *groupOp)
Definition: GroupOps.cpp:88
TargetEnvAttr lookupTargetEnvOrDefault(Operation *op)
Queries the target environment recursively from enclosing symbol table ops containing the given op or...
static LogicalResult verifyGroupNonUniformShuffleOp(OpTy op)
Definition: GroupOps.cpp:207
static LogicalResult verifyGroupOp(Op op)
Definition: GroupOps.cpp:536
static void printGroupNonUniformArithmeticOp(Operation *groupOp, OpAsmPrinter &printer)
Definition: GroupOps.cpp:63
LogicalResult extractValueFromConstOp(Operation *op, int32_t &value)
Definition: SPIRVOps.cpp:50
TargetEnvAttr getDefaultTargetEnv(MLIRContext *context)
Returns the default target environment: SPIR-V 1.0 with Shader capability and no extra extensions.
static ParseResult parseGroupNonUniformArithmeticOp(OpAsmParser &parser, OperationState &state)
Definition: GroupOps.cpp:24
Type getType(OpFoldResult ofr)
Returns the int type of the integer in ofr.
Definition: Utils.cpp:305
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs,...
Definition: Verifier.cpp:426
This is the representation of an operand reference.
This represents an operation in an abstracted form, suitable for use with the builder APIs.