22#include "mlir/Dialect/MemRef/IR/MemRef.h"
23#include "mlir/Pass/Pass.h"
25#include "llvm/ADT/StringRef.h"
26#include "llvm/Support/raw_ostream.h"
29#define GEN_PASS_DEF_AIEEXPANDLOADPDI
30#include "aie/Dialect/AIEX/Transforms/AIEXPasses.h.inc"
33#define DEBUG_TYPE "aie-expand-load-pdi"
43static LogicalResult transformLoadPdi(NpuLoadPdiOp loadPdiOp, ModuleOp moduleOp,
45 static unsigned long i = 0;
46 OpBuilder builder(loadPdiOp);
49 auto deviceRefAttr = loadPdiOp.getDeviceRefAttr();
54 auto referencedDevice = moduleOp.lookupSymbol<AIE::DeviceOp>(deviceRefAttr);
55 if (!referencedDevice) {
56 loadPdiOp.emitError(
"Referenced symbol '")
57 << deviceRefAttr.getValue() <<
"' is not a device";
62 OpBuilder::InsertionGuard guard(builder);
63 builder.setInsertionPointToStart(moduleOp.getBody());
66 std::string emptyName =
"empty_" + std::to_string(index % 2);
68 AIE::DeviceOp emptyDevice = moduleOp.lookupSymbol<AIE::DeviceOp>(emptyName);
70 auto deviceType = referencedDevice.getDevice();
71 auto loc = builder.getUnknownLoc();
72 emptyDevice = AIE::DeviceOp::create(builder, loc, deviceType,
73 builder.getStringAttr(emptyName));
74 emptyDevice.getRegion().emplaceBlock();
75 Block *deviceBlock = &emptyDevice.getRegion().front();
76 builder.setInsertionPointToEnd(deviceBlock);
77 AIE::EndOp::create(builder, loc);
80 builder.setInsertionPoint(loadPdiOp);
85 NpuLoadPdiOp::create(builder, loadPdiOp.getLoc(),
86 FlatSymbolRefAttr::get(emptyDevice.getSymNameAttr()),
87 loadPdiOp.getIdAttr(), loadPdiOp.getSizeAttr(),
88 loadPdiOp.getAddressAttr());
92 builder, referencedDevice,
"",
93 AIEToConfigurationOutputType::Transaction,
94 "loadpdi_" + std::to_string(i)))) {
95 loadPdiOp.emitError(
"Failed to generate configuration operations");
107struct AIEExpandLoadPdiPass
108 :
public xilinx::AIEX::impl::AIEExpandLoadPdiBase<AIEExpandLoadPdiPass> {
109 void getDependentDialects(DialectRegistry ®istry)
const override {
111 .insert<memref::MemRefDialect, AIE::AIEDialect, AIEX::AIEXDialect>();
114 void runOnOperation()
override {
115 auto module = getOperation();
121 SmallVector<NpuLoadPdiOp> loadPdiOps;
124 [&](NpuLoadPdiOp loadPdiOp) { loadPdiOps.push_back(loadPdiOp); });
128 for (
auto loadPdiOp : loadPdiOps) {
129 if (failed(transformLoadPdi(loadPdiOp, module, idx))) {
140std::unique_ptr<mlir::OperationPass<mlir::ModuleOp>>
142 return std::make_unique<AIEExpandLoadPdiPass>();
std::unique_ptr< mlir::OperationPass< mlir::ModuleOp > > createAIEExpandLoadPdiPass()
Include the generated interface declarations.
mlir::LogicalResult generateAndInsertConfigOps(mlir::OpBuilder &builder, xilinx::AIE::DeviceOp device, llvm::StringRef clElfDir="", AIEToConfigurationOutputType outputType=AIEToConfigurationOutputType::Transaction, std::string blockwrite_prefix="config_blockwrite_data_")