10#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
11#include "mlir/IR/DialectImplementation.h"
12#include "mlir/IR/OpDefinition.h"
13#include "mlir/IR/TypeUtilities.h"
14#include "mlir/Transforms/FoldUtils.h"
15#include "llvm/ADT/TypeSwitch.h"
23#include "aie/Dialect/AIEVec/AIE1/IR/AIEVecAIE1OpsDialect.cpp.inc"
31void AIEVecAIE1Dialect::initialize() {
34#include "aie/Dialect/AIEVec/AIE1/IR/AIEVecAIE1Ops.cpp.inc"
44static void printAddSubOp(OpAsmPrinter &p, T op) {
46 p <<
" " << op.getLhs();
48 p <<
", " << op.getRhs();
51 SmallVector<StringRef, 10> elidedAttrs;
52 for (
int idx = 0; idx < 2; ++idx) {
53 if (op.getStart(idx).empty())
54 elidedAttrs.push_back(op.getStartAttrName(idx));
55 if (op.getOffset(idx).empty())
56 elidedAttrs.push_back(op.getOffsetAttrName(idx));
57 if (op.getOffsetHi(idx).empty())
58 elidedAttrs.push_back(op.getOffsetHiAttrName(idx));
59 if (op.getSquare(idx).empty())
60 elidedAttrs.push_back(op.getSquareAttrName(idx));
62 p.printOptionalAttrDict(op->getAttrs(), elidedAttrs);
65 p <<
" : " << op.getLhs().getType() <<
", " << op.getRhs().getType();
66 p <<
", " << op.getResult().getType();
69void AddOp::print(OpAsmPrinter &p) { printAddSubOp<AddOp>(p, *
this); }
71void SubOp::print(OpAsmPrinter &p) { printAddSubOp<SubOp>(p, *
this); }
75static LogicalResult verifyAddSubOp(T op) {
77 auto resultType = llvm::dyn_cast<VectorType>(op.getResult().getType());
78 auto lhsType = llvm::dyn_cast<VectorType>(op.getLhs().getType());
79 auto rhsType = llvm::dyn_cast<VectorType>(op.getRhs().getType());
81 if (!lhsType || !rhsType || !resultType)
82 return op.emitError(
"requires vector type");
85 if (lhsType != rhsType || rhsType != resultType)
86 return op.emitError(
"all vectors must be of same type");
91LogicalResult AddOp::verify() {
return verifyAddSubOp<AddOp>(*
this); }
93LogicalResult SubOp::verify() {
return verifyAddSubOp<SubOp>(*
this); }
96static ParseResult parseAddSubOp(OpAsmParser &parser, OperationState &result) {
98 SmallVector<Type, 3> types;
99 OpAsmParser::UnresolvedOperand lhs, rhs;
102 if (parser.parseOperand(lhs) || parser.parseComma() ||
103 parser.parseOperand(rhs))
107 if (parser.parseOptionalAttrDict(result.attributes) ||
108 parser.getCurrentLocation(&typesLoc) || parser.parseColonTypeList(types))
112 if (types.size() != 3)
113 return parser.emitError(typesLoc,
"requires three types");
116 VectorType lhsType = llvm::dyn_cast<VectorType>(types[0]);
118 return parser.emitError(typesLoc,
"requires vector type");
119 VectorType rhsType = llvm::dyn_cast<VectorType>(types[1]);
121 return parser.emitError(typesLoc,
"requires vector type");
122 VectorType resultType = llvm::dyn_cast<VectorType>(types[2]);
124 return parser.emitError(typesLoc,
"requires vector type");
127 if (parser.resolveOperand(lhs, lhsType, result.operands) ||
128 parser.resolveOperand(rhs, rhsType, result.operands))
131 return parser.addTypeToList(resultType, result.types);
134ParseResult AddOp::parse(OpAsmParser &parser, OperationState &result) {
135 return parseAddSubOp(parser, result);
138ParseResult SubOp::parse(OpAsmParser &parser, OperationState &result) {
139 return parseAddSubOp(parser, result);
155 p <<
", " << op.getAcc();
166 elidedAttrs.push_back(op.getSubAttrName());
173static void printMulFMAOp(OpAsmPrinter &p, T op) {
175 p <<
" " << op.getLhs();
177 p <<
", " << op.getRhs();
182 SmallVector<StringRef, 10> elidedAttrs;
183 for (
int idx = 0; idx < 2; ++idx) {
184 if (op.getStart(idx).empty())
185 elidedAttrs.push_back(op.getStartAttrName(idx));
186 if (op.getOffset(idx).empty())
187 elidedAttrs.push_back(op.getOffsetAttrName(idx));
188 if (op.getOffsetHi(idx).empty())
189 elidedAttrs.push_back(op.getOffsetHiAttrName(idx));
190 if (op.getStep(idx).empty())
191 elidedAttrs.push_back(op.getStepAttrName(idx));
192 if (op.getSquare(idx).empty())
193 elidedAttrs.push_back(op.getSquareAttrName(idx));
196 p.printOptionalAttrDict(op->getAttrs(), elidedAttrs);
199 p <<
" : " << op.getLhs().getType() <<
", " << op.getRhs().getType();
200 p <<
", " << op.getResult().getType();
203void MulOp::print(OpAsmPrinter &p) { printMulFMAOp<MulOp>(p, *
this); }
205void FMAOp::print(OpAsmPrinter &p) { printMulFMAOp<FMAOp>(p, *
this); }
209static LogicalResult verifyMulFMAOp(T op) {
211 auto lhsType = llvm::dyn_cast<VectorType>(op.getLhs().getType());
212 auto rhsType = llvm::dyn_cast<VectorType>(op.getRhs().getType());
214 if (!lhsType || !rhsType)
215 return op.emitError(
"requires vector type");
217 auto resultType = llvm::dyn_cast<VectorType>(op.getResult().getType());
219 return op.emitError(
"requires vector type");
223 Type ltype = lhsType.getElementType();
224 Type rtype = rhsType.getElementType();
225 Type atype = resultType.getElementType();
226 unsigned ltypeWidth = ltype.getIntOrFloatBitWidth();
227 unsigned rtypeWidth = rtype.getIntOrFloatBitWidth();
228 unsigned atypeWidth = atype.getIntOrFloatBitWidth();
236 if (accLanes != rhsLanes || accLanes != lhsLanes) {
237 if (rhsLanes != 256 / rtypeWidth)
238 return op.emitError(
"incorrect rhs operand vector lanes");
239 if (lhsLanes < 2 * rhsLanes)
240 return op.emitError(
"The number of lanes in lhs operand "
241 "must be at least twice that of rhs operand");
242 if (accLanes > rhsLanes)
243 return op.emitError(
"The number of lanes in accumulator "
244 "must be less than that of rhs operand");
249 return op.emitError(
"The element type of lhs and rhs "
250 "operand vectors must match");
253 if (isa<IntegerType>(atype)) {
254 if (!isa<IntegerType>(ltype))
255 return op.emitError(
"Integer result must have integer operands");
257 if (ltypeWidth >= atypeWidth || rtypeWidth >= atypeWidth)
258 return op.emitError(
"the element type of accumulator must have "
259 "wider width than that of the operand vectors");
260 }
else if (isa<FloatType>(atype)) {
261 if (!isa<FloatType>(ltype))
262 return op.emitError(
"Floating point result must have "
263 "floating point operands");
265 if (ltypeWidth != atypeWidth || rtypeWidth != atypeWidth)
266 return op.emitError(
"the element type of accumulator must be "
267 "same width as the operand vectors");
273LogicalResult MulOp::verify() {
return verifyMulFMAOp<MulOp>(*
this); }
275LogicalResult FMAOp::verify() {
return verifyMulFMAOp<FMAOp>(*
this); }
278static ParseResult parseMulFMAOp(OpAsmParser &parser, OperationState &result,
279 bool isFMAOp =
true) {
280 llvm::SMLoc typesLoc;
281 SmallVector<Type, 3> types;
282 OpAsmParser::UnresolvedOperand lhs, rhs, acc;
285 if (parser.parseOperand(lhs) || parser.parseComma() ||
286 parser.parseOperand(rhs))
291 if (parser.parseComma() || parser.parseOperand(acc))
296 if (parser.parseOptionalAttrDict(result.attributes) ||
297 parser.getCurrentLocation(&typesLoc) || parser.parseColonTypeList(types))
301 if (types.size() != 3)
302 return parser.emitError(typesLoc,
"requires three types");
305 VectorType lhsType = llvm::dyn_cast<VectorType>(types[0]);
307 return parser.emitError(typesLoc,
"requires vector type");
308 VectorType rhsType = llvm::dyn_cast<VectorType>(types[1]);
310 return parser.emitError(typesLoc,
"requires vector type");
313 VectorType accType = llvm::dyn_cast<VectorType>(types[2]);
315 return parser.emitError(typesLoc,
"requires vector type");
318 if (parser.resolveOperand(lhs, lhsType, result.operands) ||
319 parser.resolveOperand(rhs, rhsType, result.operands))
324 if (parser.resolveOperand(acc, accType, result.operands))
328 return parser.addTypeToList(accType, result.types);
331ParseResult MulOp::parse(OpAsmParser &parser, OperationState &result) {
332 return parseMulFMAOp(parser, result,
false);
335ParseResult FMAOp::parse(OpAsmParser &parser, OperationState &result) {
336 return parseMulFMAOp(parser, result,
true);
344void SelectOp::print(OpAsmPrinter &p) {
346 p <<
" " << getXbuff();
349 p <<
", " << getYbuff();
352 SmallVector<StringRef, 10> elidedAttrs;
353 for (
int idx = 0; idx < 2; ++idx) {
354 if (getStart(idx).empty())
355 elidedAttrs.push_back(getStartAttrName(idx));
356 if (getOffset(idx).empty())
357 elidedAttrs.push_back(getOffsetAttrName(idx));
358 if (getOffsetHi(idx).empty())
359 elidedAttrs.push_back(getOffsetHiAttrName(idx));
360 if (getSquare(idx).empty())
361 elidedAttrs.push_back(getSquareAttrName(idx));
363 p.printOptionalAttrDict((*this)->getAttrs(), elidedAttrs);
366 p <<
" : " << getXbuff().getType();
368 p <<
", " << getYbuff().getType();
369 p <<
", " << getResult().getType();
373LogicalResult SelectOp::verify() {
375 VectorType resultType = llvm::dyn_cast<VectorType>(getResult().getType());
376 VectorType xbuffType = llvm::dyn_cast<VectorType>(getXbuff().getType());
378 if (!resultType || !xbuffType)
379 return emitError(
"requires vector type");
382 Type rtype = resultType.getElementType();
383 Type xtype = xbuffType.getElementType();
385 return emitError(
"types of result and xbuff must match");
389 VectorType ybuffType = llvm::dyn_cast<VectorType>(getYbuff().getType());
390 if (xbuffType != ybuffType)
391 return emitError(
"types of xbuff and ybuff must match");
397 if (sourceLanes < resultLanes)
398 return emitError(
"xbuff cannot be smaller than result");
404ParseResult SelectOp::parse(OpAsmParser &parser, OperationState &result) {
405 llvm::SMLoc typesLoc;
406 SmallVector<Type, 3> types;
407 OpAsmParser::UnresolvedOperand xbuff, ybuff;
410 if (parser.parseOperand(xbuff))
414 ParseResult hasYbuff = parser.parseOptionalComma();
415 if (hasYbuff.succeeded() && parser.parseOperand(ybuff))
419 if (parser.parseOptionalAttrDict(result.attributes) ||
420 parser.getCurrentLocation(&typesLoc) || parser.parseColonTypeList(types))
424 if (types.size() < 2)
425 return parser.emitError(typesLoc,
"requires at least two type");
428 VectorType xbuffType = llvm::dyn_cast<VectorType>(types[0]);
430 return parser.emitError(typesLoc,
"requires vector type");
431 VectorType ybuffType;
432 if (hasYbuff.succeeded()) {
433 ybuffType = llvm::dyn_cast<VectorType>(types[1]);
435 return parser.emitError(typesLoc,
"requires vector type");
437 VectorType resultType = llvm::dyn_cast<VectorType>(types.back());
439 return parser.emitError(typesLoc,
"requires vector type");
442 if (parser.resolveOperand(xbuff, xbuffType, result.operands))
445 if (hasYbuff.succeeded())
446 if (parser.resolveOperand(ybuff, ybuffType, result.operands))
449 return parser.addTypeToList(resultType, result.types);
457void ExtOp::print(OpAsmPrinter &p) {
459 p <<
" " << getSource();
462 p.printOptionalAttrDict((*this)->getAttrs());
465 p <<
" : " << getSource().getType() <<
", " << getResult().getType();
469LogicalResult ExtOp::verify() {
471 VectorType sourceType = llvm::dyn_cast<VectorType>(getSource().getType());
472 VectorType resultType = llvm::dyn_cast<VectorType>(getResult().getType());
473 if (!sourceType || !resultType)
474 return emitError(
"requires vector type");
480 if (sourceLanes / resultLanes <= 1)
481 return emitError(
"lanes in source vector must be at least "
482 "twice that of result vector");
484 if (sourceLanes % resultLanes != 0)
485 return emitError(
"lanes in result vector must be a multiple "
486 "of source vector lanes");
489 unsigned factor = sourceLanes / resultLanes;
490 if (
static_cast<unsigned>(getIndex()) >= factor)
491 return emitError(
"index out of bounds");
494 Type stype = sourceType.getElementType();
495 Type rtype = resultType.getElementType();
497 return emitError(
"source and result element type must be same");
503ParseResult ExtOp::parse(OpAsmParser &parser, OperationState &result) {
504 llvm::SMLoc typesLoc;
505 SmallVector<Type, 2> types;
506 OpAsmParser::UnresolvedOperand source;
509 if (parser.parseOperand(source))
513 if (parser.parseOptionalAttrDict(result.attributes) ||
514 parser.getCurrentLocation(&typesLoc) || parser.parseColonTypeList(types))
517 if (result.attributes.getAttrs().size() != 1)
518 return parser.emitError(typesLoc,
"requires one attribute");
521 if (types.size() != 2)
522 return parser.emitError(typesLoc,
"requires two types");
525 VectorType sourceType = llvm::dyn_cast<VectorType>(types[0]);
526 VectorType resultType = llvm::dyn_cast<VectorType>(types[1]);
527 if (!sourceType || !resultType)
528 return parser.emitError(typesLoc,
"requires vector type");
531 if (parser.resolveOperand(source, sourceType, result.operands))
534 return parser.addTypeToList(resultType, result.types);
542#define GET_OP_CLASSES
543#include "aie/Dialect/AIEVec/AIE1/IR/AIEVecAIE1Ops.cpp.inc"
void elideFMSubAttr(T op, SmallVector< StringRef, 10 > &elidedAttrs)
void printAccumulator(OpAsmPrinter &p, T op)
unsigned getVectorLaneSize(mlir::VectorType type)