13#include "mlir/Dialect/Arith/IR/Arith.h"
14#include "mlir/IR/PatternMatch.h"
15#include "mlir/Pass/Pass.h"
16#include "mlir/Transforms/WalkPatternRewriteDriver.h"
19#define GEN_PASS_DEF_AIERESOLVEADDRESSPATCHBUFFERS
20#include "aie/Dialect/AIEX/Transforms/AIEXPasses.h.inc"
30 using OpRewritePattern::OpRewritePattern;
32 LogicalResult matchAndRewrite(NpuAddressPatchOp op,
33 PatternRewriter &rewriter)
const override {
34 if (!op.getBuffer()) {
38 auto seq = op->getParentOfType<AIE::RuntimeSequenceOp>();
40 return rewriter.notifyMatchFailure(
41 op,
"must be inside a runtime sequence to resolve its host buffer");
43 std::optional<SubviewTraceResult> traced =
45 if (!traced || traced->rootArg.getOwner() != &seq.getBody().front()) {
46 return rewriter.notifyMatchFailure(
47 op,
"buffer must be an argument of the enclosing runtime sequence, "
48 "or a static contiguous view of one");
52 return rewriter.notifyMatchFailure(
53 op,
"buffer must resolve to a memref argument");
56 Value argPlus = op.getArgPlus();
57 if (traced->offsetInBytes != 0) {
61 rewriter, op.getLoc(),
62 *base +
static_cast<uint64_t
>(traced->offsetInBytes));
65 Type ty = argPlus.getType();
66 if (ty.getIntOrFloatBitWidth() < 64 &&
67 traced->offsetInBytes > std::numeric_limits<uint32_t>::max()) {
68 ty = rewriter.getIntegerType(64);
69 argPlus = arith::ExtUIOp::create(rewriter, op.getLoc(), ty, argPlus);
71 Value shift = arith::ConstantOp::create(
72 rewriter, op.getLoc(),
73 IntegerAttr::get(ty,
static_cast<int64_t
>(traced->offsetInBytes)));
74 argPlus = arith::AddIOp::create(rewriter, op.getLoc(), argPlus, shift);
78 rewriter.replaceOpWithNewOp<NpuAddressPatchOp>(
79 op, op.getAddr(), op.getAddrVal(),
static_cast<int32_t
>(*argIdx),
85struct AIEResolveAddressPatchBuffersPass
86 : xilinx::AIEX::impl::AIEResolveAddressPatchBuffersBase<
87 AIEResolveAddressPatchBuffersPass> {
89 void runOnOperation()
override {
90 RewritePatternSet patterns(&getContext());
91 patterns.add<ResolveBufferOperand>(&getContext());
92 walkAndApplyPatterns(getOperation(), std::move(patterns));
96 WalkResult unresolved = getOperation().walk([&](NpuAddressPatchOp op) {
98 op.emitOpError(
"could not resolve its buffer operand to a host buffer "
99 "index of the enclosing runtime sequence");
100 return WalkResult::interrupt();
102 return WalkResult::advance();
104 if (unresolved.wasInterrupted()) {
112std::unique_ptr<OperationPass<AIE::DeviceOp>>
114 return std::make_unique<AIEResolveAddressPatchBuffersPass>();
std::unique_ptr< mlir::OperationPass< AIE::DeviceOp > > createAIEResolveAddressPatchBuffersPass()
std::optional< SubviewTraceResult > traceSubviewToBlockArgument(Value value)
std::optional< uint64_t > getConstantInt64Operand(mlir::Value v)
mlir::Value createConstantArgPlus(mlir::OpBuilder &builder, mlir::Location loc, uint64_t value)
std::optional< unsigned > getHostBufferArgIndex(BlockArgument arg)