14#include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h"
15#include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVMPass.h"
16#include "mlir/Dialect/Arith/IR/Arith.h"
17#include "mlir/Dialect/ControlFlow/IR/ControlFlow.h"
18#include "mlir/Dialect/DLTI/DLTI.h"
19#include "mlir/Dialect/Index/IR/IndexDialect.h"
20#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
21#include "mlir/Dialect/Math/IR/Math.h"
22#include "mlir/Dialect/Ptr/IR/PtrOps.h"
23#include "mlir/Dialect/UB/IR/UBOps.h"
24#include "mlir/Dialect/Vector/IR/VectorOps.h"
25#include "mlir/IR/Attributes.h"
26#include "mlir/IR/IRMapping.h"
27#include "mlir/IR/PatternMatch.h"
28#include "mlir/Pass/Pass.h"
29#include "mlir/Tools/mlir-translate/MlirTranslateMain.h"
30#include "mlir/Transforms/DialectConversion.h"
33#define GEN_PASS_DEF_AIECORETOSTANDARD
34#include "aie/Dialect/AIE/Transforms/AIEPasses.h.inc"
42static StringRef getArchIntrinsicString(
AIEArch arch) {
55 llvm::report_fatal_error(
"unsupported arch");
59 std::tuple<const char *, std::vector<Type>, std::vector<Type>>;
62static auto getAIE1Intrinsics(OpBuilder &builder) {
63 Type int32Type = IntegerType::get(builder.getContext(), 32);
64 Type int128Type = IntegerType::get(builder.getContext(), 128);
65 Type int384Type = IntegerType::get(builder.getContext(), 384);
66 Type floatType = Float32Type::get(builder.getContext());
71 {
"debug_i32", {int32Type}, {}},
72 {
"llvm.aie.event0", {}, {}},
73 {
"llvm.aie.event1", {}, {}},
75 {int32Type, int32Type},
78 {int32Type, int128Type},
81 {int32Type, floatType},
83 {
"llvm.aie.get.ss", {int32Type}, {int32Type}},
87 {
"llvm.aie.get.fss", {int32Type}, {floatType}},
88 {
"llvm.aie.put.mcd", {int384Type}, {}},
89 {
"llvm.aie.get.scd", {}, {int384Type}},
90 {
"llvm.aie.lock.acquire.reg",
91 {int32Type, int32Type},
93 {
"llvm.aie.lock.release.reg",
94 {int32Type, int32Type},
100static auto getAIE2Intrinsics(OpBuilder &builder) {
101 Type int32Type = IntegerType::get(builder.getContext(), 32);
102 Type accType = VectorType::get({16}, int32Type);
104 {
"debug_i32", {int32Type}, {}},
105 {
"llvm.aie2.event", {int32Type}, {}},
106 {
"llvm.aie2.put.ms", {int32Type, int32Type}, {}},
107 {
"llvm.aie2.get.ss", {}, {int32Type, int32Type}},
108 {
"llvm.aie2.mcd.write.vec",
109 {accType, int32Type},
111 {
"llvm.aie2.scd.read.vec",
114 {
"llvm.aie2.acquire",
115 {int32Type, int32Type},
117 {
"llvm.aie2.release",
118 {int32Type, int32Type},
120 {
"llvm.aie2.set.ctrl.reg",
121 {int32Type, int32Type},
127static auto getAIE2pIntrinsics(OpBuilder &builder) {
128 Type int32Type = IntegerType::get(builder.getContext(), 32);
129 Type accType = VectorType::get({16}, int32Type);
131 {
"debug_i32", {int32Type}, {}},
132 {
"llvm.aie2p.event", {int32Type}, {}},
133 {
"llvm.aie2p.put.ms",
134 {int32Type, int32Type},
136 {
"llvm.aie2p.get.ss",
138 {int32Type, int32Type}},
139 {
"llvm.aie2p.mcd.write.vec",
140 {accType, int32Type},
142 {
"llvm.aie2p.scd.read.vec",
145 {
"llvm.aie2p.acquire",
146 {int32Type, int32Type},
148 {
"llvm.aie2p.release",
149 {int32Type, int32Type},
151 {
"llvm.aie2p.set.ctrl.reg",
152 {int32Type, int32Type},
158static void declareAIEIntrinsics(
AIEArch arch, OpBuilder &builder) {
159 auto registerIntrinsics = [&builder](
const IntrinsicDecls &functions) {
160 for (
auto &i : functions) {
161 auto [name, argTypes, retTypes] = i;
162 func::FuncOp::create(
163 builder, builder.getUnknownLoc(), name,
164 FunctionType::get(builder.getContext(), argTypes, retTypes))
170 registerIntrinsics(getAIE1Intrinsics(builder));
173 registerIntrinsics(getAIE2Intrinsics(builder));
176 registerIntrinsics(getAIE2pIntrinsics(builder));
178 case AIEArch::AIE2ps:
182 llvm::report_fatal_error(
"unsupported arch");
186template <
typename OpTy>
187static void outlineOps(DeviceOp device) {
188 SmallVector<OpTy, 16> ops;
189 for (
const auto &op : device.getOps<OpTy>())
192 for (
const auto &op : ops)
193 op->moveBefore(device);
197template <
typename MyAIEOp>
198struct AIEOpRemoval : OpConversionPattern<MyAIEOp> {
199 using OpConversionPattern<MyAIEOp>::OpConversionPattern;
200 using OpAdaptor =
typename MyAIEOp::Adaptor;
203 AIEOpRemoval(MLIRContext *context, ModuleOp &m, PatternBenefit benefit = 1)
204 : OpConversionPattern<MyAIEOp>(context, benefit), module(m) {}
208 ConversionPatternRewriter &rewriter)
const override {
209 rewriter.eraseOp(op);
214struct AIEDebugOpToStdLowering : OpConversionPattern<DebugOp> {
215 using OpConversionPattern::OpConversionPattern;
218 AIEDebugOpToStdLowering(MLIRContext *context, ModuleOp &m,
219 PatternBenefit benefit = 1)
220 : OpConversionPattern(context, benefit), module(m) {}
223 matchAndRewrite(DebugOp op, OpAdaptor adaptor,
224 ConversionPatternRewriter &rewriter)
const override {
225 std::string funcName =
"debug_i32";
226 auto func =
module.lookupSymbol<func::FuncOp>(funcName);
228 return op.emitOpError(
"Could not find the intrinsic function ")
230 SmallVector<Value, 1> args;
231 args.push_back(op.getArg());
232 func::CallOp::create(rewriter, op.getLoc(), func, args);
233 rewriter.eraseOp(op);
238struct AIEPutStreamToStdLowering : OpConversionPattern<PutStreamOp> {
239 using OpConversionPattern::OpConversionPattern;
242 AIEPutStreamToStdLowering(MLIRContext *context, ModuleOp &m,
243 PatternBenefit benefit = 1)
244 : OpConversionPattern(context, benefit), module(m) {}
247 matchAndRewrite(PutStreamOp op, OpAdaptor adaptor,
248 ConversionPatternRewriter &rewriter)
const override {
249 auto device = op->getParentOfType<DeviceOp>();
250 const auto &targetModel = device.getTargetModel();
251 std::string funcName;
252 if (targetModel.getTargetArch() == AIEArch::AIE1)
253 funcName =
"llvm.aie.put.";
254 else if (targetModel.getTargetArch() == AIEArch::AIE2)
255 funcName =
"llvm.aie2.put.";
257 funcName =
"llvm.aie2p.put.";
259 if (op.isWideStream())
261 else if (op.isFloatStream())
266 auto putMSFunc =
module.lookupSymbol<func::FuncOp>(funcName);
268 return op.emitOpError(
"Could not find the intrinsic function ")
270 SmallVector<Value, 2> args;
271 if (targetModel.getTargetArch() == AIEArch::AIE1) {
272 args.push_back(op.getChannel());
273 args.push_back(op.getStreamValue());
275 args.push_back(op.getStreamValue());
276 args.push_back(arith::ConstantOp::create(
277 rewriter, op.getLoc(), IntegerType::get(rewriter.getContext(), 32),
278 rewriter.getI32IntegerAttr(0)));
280 func::CallOp::create(rewriter, op.getLoc(), putMSFunc, args);
281 rewriter.eraseOp(op);
286struct AIEGetStreamToStdLowering : OpConversionPattern<GetStreamOp> {
287 using OpConversionPattern::OpConversionPattern;
290 AIEGetStreamToStdLowering(MLIRContext *context, ModuleOp &m,
291 PatternBenefit benefit = 1)
292 : OpConversionPattern(context, benefit), module(m) {}
295 matchAndRewrite(GetStreamOp op, OpAdaptor adaptor,
296 ConversionPatternRewriter &rewriter)
const override {
297 auto device = op->getParentOfType<DeviceOp>();
298 const auto &targetModel = device.getTargetModel();
299 std::string funcName;
300 if (targetModel.getTargetArch() == AIEArch::AIE1)
301 funcName =
"llvm.aie.get.";
302 else if (targetModel.getTargetArch() == AIEArch::AIE2)
303 funcName =
"llvm.aie2.get.";
305 funcName =
"llvm.aie2p.get.";
307 if (op.isWideStream())
309 else if (op.isFloatStream())
314 auto getSSFunc =
module.lookupSymbol<func::FuncOp>(funcName);
316 return op.emitOpError(
"Could not find the intrinsic function ")
318 SmallVector<Value, 2> args;
319 if (targetModel.getTargetArch() == AIEArch::AIE1)
320 args.push_back(op.getChannel());
322 func::CallOp::create(rewriter, op.getLoc(), getSSFunc, args);
323 rewriter.replaceOp(op, getSSCall.getResult(0));
329struct AIEPutCascadeToStdLowering : OpConversionPattern<PutCascadeOp> {
330 using OpConversionPattern::OpConversionPattern;
333 AIEPutCascadeToStdLowering(MLIRContext *context, ModuleOp &m,
334 PatternBenefit benefit = 1)
335 : OpConversionPattern(context, benefit), module(m) {}
338 matchAndRewrite(PutCascadeOp op, OpAdaptor adaptor,
339 ConversionPatternRewriter &rewriter)
const override {
340 auto device = op->getParentOfType<DeviceOp>();
341 const auto &targetModel = device.getTargetModel();
342 std::string funcName;
343 if (targetModel.getTargetArch() == AIEArch::AIE1)
344 funcName =
"llvm.aie.put.mcd";
345 else if (targetModel.getTargetArch() == AIEArch::AIE2)
346 funcName =
"llvm.aie2.mcd.write.vec";
348 funcName =
"llvm.aie2p.mcd.write.vec";
349 auto putMCDFunc =
module.lookupSymbol<func::FuncOp>(funcName);
351 return op.emitOpError(
"Could not find the intrinsic function ")
353 SmallVector<Value, 2> args;
354 Value cascadeValue = op.getCascadeValue();
357 Type expectedInputType = putMCDFunc.getFunctionType().getInput(0);
358 Type actualInputType = cascadeValue.getType();
360 if (expectedInputType != actualInputType) {
363 cascadeValue = vector::BitCastOp::create(rewriter, op.getLoc(),
364 expectedInputType, cascadeValue);
367 args.push_back(cascadeValue);
368 if (isa<AIE2TargetModel>(targetModel))
369 args.push_back(arith::ConstantOp::create(
370 rewriter, op.getLoc(), IntegerType::get(rewriter.getContext(), 32),
371 rewriter.getI32IntegerAttr(1)));
373 func::CallOp::create(rewriter, op.getLoc(), putMCDFunc, args);
374 rewriter.eraseOp(op);
379struct AIEGetCascadeToStdLowering : OpConversionPattern<GetCascadeOp> {
380 using OpConversionPattern::OpConversionPattern;
383 AIEGetCascadeToStdLowering(MLIRContext *context, ModuleOp &m,
384 PatternBenefit benefit = 1)
385 : OpConversionPattern(context, benefit), module(m) {}
388 matchAndRewrite(GetCascadeOp op, OpAdaptor adaptor,
389 ConversionPatternRewriter &rewriter)
const override {
390 auto device = op->getParentOfType<DeviceOp>();
391 const auto &targetModel = device.getTargetModel();
392 std::string funcName;
393 if (targetModel.getTargetArch() == AIEArch::AIE1)
394 funcName =
"llvm.aie.get.scd";
395 else if (targetModel.getTargetArch() == AIEArch::AIE2)
396 funcName =
"llvm.aie2.scd.read.vec";
398 funcName =
"llvm.aie2p.scd.read.vec";
399 auto getSCDFunc =
module.lookupSymbol<func::FuncOp>(funcName);
401 return op.emitOpError(
"Could not find the intrinsic function ")
403 SmallVector<Value, 2> args;
404 if (isa<AIE2TargetModel>(targetModel))
405 args.push_back(arith::ConstantOp::create(
406 rewriter, op.getLoc(), IntegerType::get(rewriter.getContext(), 32),
407 rewriter.getI32IntegerAttr(1)));
410 func::CallOp::create(rewriter, op.getLoc(), getSCDFunc, args);
411 Value result = getSCDCall.getResult(0);
414 Type expectedType = op.getResult().getType();
415 Type intrinsicReturnType = result.getType();
417 if (expectedType != intrinsicReturnType) {
420 result = vector::BitCastOp::create(rewriter, op.getLoc(), expectedType,
424 rewriter.replaceOp(op, result);
429struct AIEUseLockToStdLowering : OpConversionPattern<UseLockOp> {
430 using OpConversionPattern::OpConversionPattern;
433 AIEUseLockToStdLowering(MLIRContext *context, ModuleOp &m,
434 PatternBenefit benefit = 1)
435 : OpConversionPattern(context, benefit), module(m) {}
437 matchAndRewrite(UseLockOp useLock, OpAdaptor adaptor,
438 ConversionPatternRewriter &rewriter)
const override {
439 if (!isa<DeviceOp>(useLock->getParentOp())) {
440 auto device = useLock->getParentOfType<DeviceOp>();
442 return module.emitOpError("Device Not found!");
444 const auto &targetModel = device.getTargetModel();
447 std::string funcName;
448 if (targetModel.getTargetArch() == AIEArch::AIE1)
449 funcName =
"llvm.aie.lock.";
450 else if (targetModel.getTargetArch() == AIEArch::AIE2)
451 funcName =
"llvm.aie2.";
453 funcName =
"llvm.aie2p.";
454 if (useLock.acquire() || useLock.acquireGE())
455 funcName +=
"acquire";
456 else if (useLock.release())
457 funcName +=
"release";
458 if (targetModel.getTargetArch() == AIEArch::AIE1)
461 auto useLockFunc =
module.lookupSymbol<func::FuncOp>(funcName);
463 return useLock.emitOpError(
"Could not find the intrinsic function!");
465 SmallVector<Value, 2> args;
466 auto i32Ty = IntegerType::get(rewriter.getContext(), 32);
467 args.push_back(arith::IndexCastOp::create(rewriter, useLock.getLoc(),
468 i32Ty, useLock.getLock()));
470 Value value = adaptor.getValue();
473 if (useLock.acquireGE()) {
474 Value zero = arith::ConstantOp::create(
475 rewriter, useLock.getLoc(), i32Ty, rewriter.getI32IntegerAttr(0));
476 value = arith::SubIOp::create(rewriter, useLock.getLoc(), zero, value);
478 args.push_back(value);
480 func::CallOp::create(rewriter, useLock.getLoc(), useLockFunc, args);
482 rewriter.eraseOp(useLock);
487struct AIEBufferToStandard : OpConversionPattern<BufferOp> {
488 using OpConversionPattern::OpConversionPattern;
490 AIEBufferToStandard(MLIRContext *context, ModuleOp &m,
491 PatternBenefit benefit = 1)
492 : OpConversionPattern(context, benefit), module(m) {}
494 matchAndRewrite(BufferOp buffer, OpAdaptor adaptor,
495 ConversionPatternRewriter &rewriter)
const override {
497 if (buffer.getCoreData()) {
498 rewriter.eraseOp(buffer);
501 rewriter.setInsertionPointToStart(module.getBody());
502 auto t = llvm::cast<MemRefType>(buffer.getType());
503 auto symName = buffer.name().getValue();
511 memref::GlobalOp::create(rewriter, buffer.getLoc(), symName,
512 rewriter.getStringAttr(
"public"), buffer.getType(),
516 for (
auto &use : make_early_inc_range(buffer.getResult().getUses())) {
517 Operation *user = use.getOwner();
518 rewriter.setInsertionPoint(user);
520 memref::GetGlobalOp::create(rewriter, buffer.getLoc(), t, symName);
522 memref::AssumeAlignmentOp::create(rewriter, buffer.getLoc(), allocated,
525 use.set(allocated.getResult());
528 rewriter.eraseOp(buffer);
533struct AIECoreToStandardFunc : OpConversionPattern<CoreOp> {
534 using OpConversionPattern::OpConversionPattern;
537 DenseMap<Operation *, SmallVector<BufferOp, 4>> &tileToBuffers;
541 AIECoreToStandardFunc(
542 MLIRContext *context, ModuleOp &m, IRMapping &mapper,
543 DenseMap<Operation *, SmallVector<BufferOp, 4>> &tileToBuffers,
544 PatternBenefit benefit = 1,
int tileCol = 1,
int tileRow = 1)
545 : OpConversionPattern(context, benefit), module(m), mapper(mapper),
546 tileToBuffers(tileToBuffers), tileCol(tileCol), tileRow(tileRow) {}
549 matchAndRewrite(CoreOp op, OpAdaptor adaptor,
550 ConversionPatternRewriter &rewriter)
const override {
552 int col = op.colIndex();
553 int row = op.rowIndex();
556 if ((tileRow != row && tileRow != -1) ||
557 (tileCol != col && tileCol != -1)) {
558 rewriter.eraseOp(op);
563 rewriter.setInsertionPointAfter(op->getParentOp());
567 func::FuncOp::create(rewriter, op.getLoc(), coreName,
568 FunctionType::get(rewriter.getContext(), {}, {}));
570 rewriter.cloneRegionBefore(op.getBody(), coreFunc.getBody(),
571 coreFunc.getBody().begin(), mapper);
578 bool hasIntegerSRS =
false;
579 bool hasBF16Matmul =
false;
580 coreFunc.walk([&](Operation *childOp) {
581 StringRef opName = childOp->getName().getStringRef();
582 if (opName ==
"aievec.srs") {
587 if (childOp->getNumResults() > 0) {
588 auto resultType = childOp->getResult(0).getType();
589 if (
auto vecType = dyn_cast<VectorType>(resultType)) {
590 if (vecType.getElementType().isInteger())
591 hasIntegerSRS =
true;
597 if (opName ==
"aievec.matmul" || opName ==
"aievec.matmul_aie2p") {
598 if (childOp->getNumOperands() > 0) {
599 auto lhsType = childOp->getOperand(0).getType();
600 if (
auto vecType = dyn_cast<VectorType>(lhsType))
601 if (vecType.getElementType().isBF16())
602 hasBF16Matmul =
true;
606 if (hasSRS || hasBF16Matmul) {
607 auto device = op->getParentOfType<DeviceOp>();
609 AIEArch arch = device.getTargetModel().getTargetArch();
610 if (arch == AIEArch::AIE2 || arch == AIEArch::AIE2p) {
611 std::string ctrlRegFuncName = (arch == AIEArch::AIE2p)
612 ?
"llvm.aie2p.set.ctrl.reg"
613 :
"llvm.aie2.set.ctrl.reg";
614 auto ctrlRegFunc =
module.lookupSymbol<func::FuncOp>(ctrlRegFuncName);
616 Block &entryBlock = coreFunc.getBody().front();
617 rewriter.setInsertionPointToStart(&entryBlock);
618 Location loc = op.getLoc();
628 int rndRegIdx = (arch == AIEArch::AIE2p) ? 1 : 6;
630 auto cSatIdx = arith::ConstantOp::create(
631 rewriter, loc, rewriter.getI32IntegerAttr(satRegIdx));
632 auto c1 = arith::ConstantOp::create(rewriter, loc,
633 rewriter.getI32IntegerAttr(1));
634 func::CallOp::create(rewriter, loc, ctrlRegFunc,
635 ValueRange{cSatIdx, c1});
646 int roundingMode = hasIntegerSRS && !hasBF16Matmul ? 9 : 12;
647 auto cRndIdx = arith::ConstantOp::create(
648 rewriter, loc, rewriter.getI32IntegerAttr(rndRegIdx));
649 auto cRoundingMode = arith::ConstantOp::create(
650 rewriter, loc, rewriter.getI32IntegerAttr(roundingMode));
651 func::CallOp::create(rewriter, loc, ctrlRegFunc,
652 ValueRange{cRndIdx, cRoundingMode});
659 coreFunc.getBody().walk([&](Operation *childOp) {
660 rewriter.setInsertionPointAfter(childOp);
662 if (isa<EndOp>(childOp)) {
663 func::ReturnOp::create(rewriter, childOp->getLoc(), ValueRange({}));
664 rewriter.eraseOp(childOp);
668 rewriter.eraseOp(op);
674struct AIEEventOpToStdLowering : OpConversionPattern<EventOp> {
675 using OpConversionPattern::OpConversionPattern;
678 AIEEventOpToStdLowering(MLIRContext *context, ModuleOp &m,
679 PatternBenefit benefit = 1)
680 : OpConversionPattern(context, benefit), module(m) {}
683 matchAndRewrite(EventOp op, OpAdaptor adaptor,
684 ConversionPatternRewriter &rewriter)
const override {
685 auto device = op->getParentOfType<DeviceOp>();
686 std::string funcName;
687 SmallVector<Value, 1> args;
688 switch (device.getTargetModel().getTargetArch()) {
690 funcName =
"llvm.aie.event" + std::to_string(op.getVal());
693 funcName =
"llvm.aie2.event";
694 args.push_back(arith::ConstantOp::create(
695 rewriter, op.getLoc(), rewriter.getI32Type(),
696 rewriter.getI32IntegerAttr(op.getVal())));
699 funcName =
"llvm.aie2p.event";
700 args.push_back(arith::ConstantOp::create(
701 rewriter, op.getLoc(), rewriter.getI32Type(),
702 rewriter.getI32IntegerAttr(op.getVal())));
704 case AIEArch::AIE2ps:
708 return op.emitOpError(
709 "aie.event is not supported on this device's architecture");
711 auto eventFunc =
module.lookupSymbol<func::FuncOp>(funcName);
713 return op.emitOpError(
"Could not find the intrinsic function ")
715 func::CallOp::create(rewriter, op.getLoc(), eventFunc, args);
716 rewriter.eraseOp(op);
721struct AIECoreToStandardPass
722 : xilinx::AIE::impl::AIECoreToStandardBase<AIECoreToStandardPass> {
723 AIECoreToStandardPass() =
default;
724 AIECoreToStandardPass(
const AIECoreToStandardOptions &options) {
725 deviceName = options.deviceName;
726 tileCol = options.tileCol;
727 tileRow = options.tileRow;
730 void runOnOperation()
override {
732 ModuleOp m = getOperation();
733 OpBuilder builder = OpBuilder::atBlockEnd(m.getBody());
735 DeviceOp deviceOp = DeviceOp::getForSymbolInModuleOrError(m, deviceName);
737 return signalPassFailure();
739 const auto &targetModel = deviceOp.getTargetModel();
742 if (
auto dlAttr = deviceOp->getAttr(DLTIDialect::kDataLayoutAttrName)) {
743 m->setAttr(DLTIDialect::kDataLayoutAttrName, dlAttr);
748 m->setAttr(LLVM::LLVMDialect::getTargetTripleAttrName(),
749 builder.getStringAttr(
750 getArchIntrinsicString(targetModel.getTargetArch())));
752 DenseMap<Operation *, SmallVector<BufferOp, 4>> tileToBuffers;
758 builder.setInsertionPointToStart(m.getBody());
759 declareAIEIntrinsics(targetModel.getTargetArch(), builder);
762 ConversionTarget target(getContext());
763 target.addLegalDialect<func::FuncDialect>();
764 target.addLegalDialect<cf::ControlFlowDialect>();
765 target.addLegalDialect<memref::MemRefDialect>();
766 target.addLegalDialect<VectorDialect>();
767 target.addLegalDialect<aievec::AIEVecDialect>();
768 target.addLegalDialect<arith::ArithDialect>();
769 target.addLegalDialect<ub::UBDialect>();
770 target.addLegalDialect<math::MathDialect>();
771 target.addLegalDialect<index::IndexDialect>();
772 target.addLegalDialect<ptr::PtrDialect>();
773 target.addLegalOp<func::FuncOp, ModuleOp, UnrealizedConversionCastOp>();
775 RewritePatternSet patterns(&getContext());
776 patterns.add<AIEPutStreamToStdLowering, AIEGetStreamToStdLowering,
777 AIEPutCascadeToStdLowering, AIEGetCascadeToStdLowering,
778 AIEDebugOpToStdLowering, AIEUseLockToStdLowering,
779 AIEEventOpToStdLowering>(m.getContext(), m);
781 patterns.add<AIEBufferToStandard>(m.getContext(), m, 1);
782 if (failed(applyPartialConversion(deviceOp, target, std::move(patterns))))
783 return signalPassFailure();
785 RewritePatternSet outlinePatterns(&getContext());
786 outlinePatterns.add<AIECoreToStandardFunc>(m.getContext(), m, mapper,
789 if (failed(applyPartialConversion(deviceOp, target,
790 std::move(outlinePatterns))))
791 return signalPassFailure();
795 outlineOps<memref::GlobalOp>(deviceOp);
796 outlineOps<func::FuncOp>(deviceOp);
798 RewritePatternSet removepatterns(&getContext());
800 AIEOpRemoval<DeviceOp>, AIEOpRemoval<TileOp>, AIEOpRemoval<FlowOp>,
801 AIEOpRemoval<MemOp>, AIEOpRemoval<ShimDMAOp>, AIEOpRemoval<ShimMuxOp>,
802 AIEOpRemoval<SwitchboxOp>, AIEOpRemoval<LockOp>, AIEOpRemoval<BufferOp>,
803 AIEOpRemoval<ExternalBufferOp>, AIEOpRemoval<ShimDMAAllocationOp>,
804 AIEOpRemoval<CascadeFlowOp>, AIEOpRemoval<ConfigureCascadeOp>>(
807 if (failed(applyPartialConversion(m, target, std::move(removepatterns))))
808 return signalPassFailure();
814 return std::make_unique<AIECoreToStandardPass>();
817std::unique_ptr<OperationPass<ModuleOp>>
819 return std::make_unique<AIECoreToStandardPass>(options);
std::tuple< const char *, std::vector< Type >, std::vector< Type > > IntrinsicDecl
std::vector< IntrinsicDecl > IntrinsicDecls
std::string coreFrameSymbolName(int col, int row)
std::unique_ptr< mlir::OperationPass< mlir::ModuleOp > > createAIECoreToStandardPass()
AIEOpRemoval(MLIRContext *context, PatternBenefit benefit=1)
LogicalResult matchAndRewrite(MyOp op, OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override