diff --git a/lib/Conversion/AIEToConfiguration/AIEToConfiguration.cpp b/lib/Conversion/AIEToConfiguration/AIEToConfiguration.cpp index 4cf93cd63b2..c6477330233 100644 --- a/lib/Conversion/AIEToConfiguration/AIEToConfiguration.cpp +++ b/lib/Conversion/AIEToConfiguration/AIEToConfiguration.cpp @@ -450,12 +450,10 @@ static LogicalResult generateTransactions(AIERTControl &ctl, // Translate vector of TransactionBinaryOperation to a sequence of transaction // ops (npu.write32, npu.maskwrite32, npu.blockwrite). static LogicalResult -emitTransactionOps(OpBuilder &builder, +emitTransactionOps(OpBuilder &builder, Location loc, std::vector &operations, std::vector &global_data) { - auto loc = builder.getUnknownLoc(); - // create the txn ops for (auto [op, payload] : llvm::zip(operations, global_data)) { @@ -531,11 +529,10 @@ emitTransactionOps(OpBuilder &builder, // Translate vector of TransactionBinaryOperation to a sequence of control // packet ops. static LogicalResult -emitControlPacketOps(OpBuilder &builder, +emitControlPacketOps(OpBuilder &builder, Location loc, std::vector &operations, std::vector &global_data) { - auto loc = builder.getUnknownLoc(); auto ctx = builder.getContext(); // create the control packet ops @@ -636,17 +633,21 @@ static LogicalResult convertTransactionOpsToMLIR( std::vector &operations, std::string blockwrite_prefix = "config_blockwrite_data_") { - auto loc = builder.getUnknownLoc(); - // for each blockwrite in the binary, create a GlobalOp with the data at the // device level std::vector global_data; + Operation *parentOp = builder.getBlock()->getParentOp(); + DeviceOp device = llvm::dyn_cast(parentOp); + if (!device) { + device = parentOp->getParentOfType(); + } + if (!device) { + parentOp->emitError( + "expected insertion point to be nested under an aie.device op"); + return failure(); + } + Location loc = device.getLoc(); { - DeviceOp device = - llvm::dyn_cast(builder.getBlock()->getParentOp()); - if (!device) { - device = builder.getBlock()->getParentOp()->getParentOfType(); - } OpBuilder::InsertionGuard guard(builder); builder.setInsertionPointToStart(device.getBody()); int id = 0; @@ -676,10 +677,10 @@ static LogicalResult convertTransactionOpsToMLIR( // create the txn ops if (outputType == AIE::AIEToConfigurationOutputType::Transaction) { - if (failed(emitTransactionOps(builder, operations, global_data))) + if (failed(emitTransactionOps(builder, loc, operations, global_data))) return failure(); } else if (outputType == AIE::AIEToConfigurationOutputType::ControlPacket) { - if (failed(emitControlPacketOps(builder, operations, global_data))) + if (failed(emitControlPacketOps(builder, loc, operations, global_data))) return failure(); // resolve mask writes; control packet doesn't natively support mask write. if (failed(orConsecutiveWritesOnSameAddr(builder.getBlock()))) @@ -784,7 +785,7 @@ convertAIEToConfiguration(AIE::DeviceOp device, StringRef clElfDir, // and collect them in a vector. If there are none, create a new runtime // sequence. Otherwise assume the insertion point is the first // aiex.configure op. - auto loc = builder.getUnknownLoc(); + auto loc = device.getLoc(); SmallVector configureOps; device.walk([&](AIEX::ConfigureOp op) { configureOps.push_back(op); }); diff --git a/lib/Dialect/AIE/IR/AIEDialect.cpp b/lib/Dialect/AIE/IR/AIEDialect.cpp index 4edfff37418..1747a138dec 100644 --- a/lib/Dialect/AIE/IR/AIEDialect.cpp +++ b/lib/Dialect/AIE/IR/AIEDialect.cpp @@ -1610,8 +1610,8 @@ TileOp TileOp::getOrCreate(mlir::OpBuilder builder, DeviceOp device, int col, OpBuilder::InsertionGuard guard(builder); mlir::Block &device_start_block = *device.getBodyRegion().begin(); builder.setInsertionPointToStart(&device_start_block); - tile = TileOp::create(builder, builder.getUnknownLoc(), - builder.getIndexType(), col, row); + tile = TileOp::create(builder, device.getLoc(), builder.getIndexType(), col, + row); } return tile; } diff --git a/lib/Dialect/AIE/Transforms/AIECanonicalizeDevice.cpp b/lib/Dialect/AIE/Transforms/AIECanonicalizeDevice.cpp index beb0a88b156..3413c3061b3 100644 --- a/lib/Dialect/AIE/Transforms/AIECanonicalizeDevice.cpp +++ b/lib/Dialect/AIE/Transforms/AIECanonicalizeDevice.cpp @@ -42,7 +42,7 @@ struct AIECanonicalizeDevicePass // the new op quite yet. OpBuilder builder(moduleOp->getContext()); - Location location = builder.getUnknownLoc(); + Location location = moduleOp.getLoc(); auto deviceOp = DeviceOp::create( builder, location, AIEDeviceAttr::get(builder.getContext(), AIEDevice::xcvc1902), diff --git a/lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp b/lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp index d01ff4558b0..879bb2b99bd 100644 --- a/lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp +++ b/lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp @@ -211,7 +211,7 @@ struct AIEDebugOpToStdLowering : OpConversionPattern { << funcName; SmallVector args; args.push_back(op.getArg()); - func::CallOp::create(rewriter, rewriter.getUnknownLoc(), func, args); + func::CallOp::create(rewriter, op.getLoc(), func, args); rewriter.eraseOp(op); return success(); } @@ -259,7 +259,7 @@ struct AIEPutStreamToStdLowering : OpConversionPattern { rewriter, op.getLoc(), IntegerType::get(rewriter.getContext(), 32), rewriter.getI32IntegerAttr(0))); // tlast } - func::CallOp::create(rewriter, rewriter.getUnknownLoc(), putMSFunc, args); + func::CallOp::create(rewriter, op.getLoc(), putMSFunc, args); rewriter.eraseOp(op); return success(); } @@ -300,8 +300,8 @@ struct AIEGetStreamToStdLowering : OpConversionPattern { SmallVector args; if (targetModel.getTargetArch() == AIEArch::AIE1) args.push_back(op.getChannel()); - auto getSSCall = func::CallOp::create(rewriter, rewriter.getUnknownLoc(), - getSSFunc, args); + auto getSSCall = + func::CallOp::create(rewriter, op.getLoc(), getSSFunc, args); rewriter.replaceOp(op, getSSCall.getResult(0)); // Capture TLAST in AIEv2? return success(); @@ -352,7 +352,7 @@ struct AIEPutCascadeToStdLowering : OpConversionPattern { rewriter, op.getLoc(), IntegerType::get(rewriter.getContext(), 32), rewriter.getI32IntegerAttr(1))); // enable - func::CallOp::create(rewriter, rewriter.getUnknownLoc(), putMCDFunc, args); + func::CallOp::create(rewriter, op.getLoc(), putMCDFunc, args); rewriter.eraseOp(op); return success(); } @@ -388,8 +388,8 @@ struct AIEGetCascadeToStdLowering : OpConversionPattern { rewriter, op.getLoc(), IntegerType::get(rewriter.getContext(), 32), rewriter.getI32IntegerAttr(1))); // enable - auto getSCDCall = func::CallOp::create(rewriter, rewriter.getUnknownLoc(), - getSCDFunc, args); + auto getSCDCall = + func::CallOp::create(rewriter, op.getLoc(), getSCDFunc, args); Value result = getSCDCall.getResult(0); // Check if we need a bitcast @@ -459,8 +459,7 @@ struct AIEUseLockToStdLowering : OpConversionPattern { IntegerType::get(rewriter.getContext(), 32), rewriter.getI32IntegerAttr(lockValue))); - func::CallOp::create(rewriter, rewriter.getUnknownLoc(), useLockFunc, - args); + func::CallOp::create(rewriter, useLock.getLoc(), useLockFunc, args); } rewriter.eraseOp(useLock); return success(); @@ -490,7 +489,7 @@ struct AIEBufferToStandard : OpConversionPattern { // prevent duplication in the data section of the elf/object file) if ((tileRow != row && tileRow != -1) || (tileCol != col && tileCol != -1)) initValue = nullptr; - memref::GlobalOp::create(rewriter, rewriter.getUnknownLoc(), symName, + memref::GlobalOp::create(rewriter, buffer.getLoc(), symName, rewriter.getStringAttr("public"), buffer.getType(), initValue, /*constant*/ false, /*alignment*/ nullptr); @@ -498,11 +497,11 @@ struct AIEBufferToStandard : OpConversionPattern { for (auto &use : make_early_inc_range(buffer.getResult().getUses())) { Operation *user = use.getOwner(); rewriter.setInsertionPoint(user); - auto allocated = memref::GetGlobalOp::create( - rewriter, rewriter.getUnknownLoc(), t, symName); + auto allocated = + memref::GetGlobalOp::create(rewriter, buffer.getLoc(), t, symName); // Assume that buffers are aligned so they can be vectorized. - memref::AssumeAlignmentOp::create(rewriter, rewriter.getUnknownLoc(), - allocated, 32); + memref::AssumeAlignmentOp::create(rewriter, buffer.getLoc(), allocated, + 32); use.set(allocated.getResult()); } @@ -547,7 +546,7 @@ struct AIECoreToStandardFunc : OpConversionPattern { std::string coreName("core_" + std::to_string(col) + "_" + std::to_string(row)); auto coreFunc = - func::FuncOp::create(rewriter, rewriter.getUnknownLoc(), coreName, + func::FuncOp::create(rewriter, op.getLoc(), coreName, FunctionType::get(rewriter.getContext(), {}, {})); rewriter.cloneRegionBefore(op.getBody(), coreFunc.getBody(), @@ -641,8 +640,7 @@ struct AIECoreToStandardFunc : OpConversionPattern { rewriter.setInsertionPointAfter(childOp); if (isa(childOp)) { - func::ReturnOp::create(rewriter, rewriter.getUnknownLoc(), - ValueRange({})); + func::ReturnOp::create(rewriter, childOp->getLoc(), ValueRange({})); rewriter.eraseOp(childOp); } }); @@ -701,7 +699,7 @@ struct AIEEventOpToStdLowering : OpConversionPattern { if (!eventFunc) return op.emitOpError("Could not find the intrinsic function ") << funcName; - func::CallOp::create(rewriter, rewriter.getUnknownLoc(), eventFunc, args); + func::CallOp::create(rewriter, op.getLoc(), eventFunc, args); rewriter.eraseOp(op); return success(); } diff --git a/lib/Dialect/AIE/Transforms/AIECreatePathFindFlows.cpp b/lib/Dialect/AIE/Transforms/AIECreatePathFindFlows.cpp index 99b6b968b95..8e02c0b086a 100644 --- a/lib/Dialect/AIE/Transforms/AIECreatePathFindFlows.cpp +++ b/lib/Dialect/AIE/Transforms/AIECreatePathFindFlows.cpp @@ -46,8 +46,8 @@ struct ConvertFlowsToInterconnect : OpConversionPattern { auto point = rewriter.saveInsertionPoint(); rewriter.setInsertionPoint(b.getTerminator()); - ConnectOp::create(rewriter, rewriter.getUnknownLoc(), inBundle, inIndex, - outBundle, outIndex); + ConnectOp::create(rewriter, flowOp.getLoc(), inBundle, inIndex, outBundle, + outIndex); rewriter.restoreInsertionPoint(point); @@ -832,13 +832,13 @@ AIEPathfinderPass::runOnPacketFlow(DeviceOp device, OpBuilder &builder, Operation *tileOp = map.second; TileOp tile = cast(map.second); TileID tileId = tile.getTileID(); + Location tileLoc = tile.getLoc(); // Create a switchbox for the routes and insert inside it. builder.setInsertionPointAfter(tileOp); SwitchboxOp swbox = analyzer.getSwitchbox(builder, tile.colIndex(), tile.rowIndex()); - SwitchboxOp::ensureTerminator(swbox.getConnections(), builder, - builder.getUnknownLoc()); + SwitchboxOp::ensureTerminator(swbox.getConnections(), builder, tileLoc); Block &b = swbox.getConnections().front(); builder.setInsertionPoint(b.getTerminator()); @@ -859,8 +859,7 @@ AIEPathfinderPass::runOnPacketFlow(DeviceOp device, OpBuilder &builder, if (amselOpNeededVector[amselValue]) { int arbiterID = a; int msel = i; - auto amsel = AMSelOp::create(builder, builder.getUnknownLoc(), - arbiterID, msel); + auto amsel = AMSelOp::create(builder, tileLoc, arbiterID, msel); amselOps[amselValue] = amsel; } } @@ -885,8 +884,8 @@ AIEPathfinderPass::runOnPacketFlow(DeviceOp device, OpBuilder &builder, amsels.push_back(amselOps[msel]); } - MasterSetOp::create(builder, builder.getUnknownLoc(), - builder.getIndexType(), bundle, channel, amsels, + MasterSetOp::create(builder, tileLoc, builder.getIndexType(), bundle, + channel, amsels, keepPktHeaderAttr[{tileId, tileMaster}]); } @@ -915,10 +914,9 @@ AIEPathfinderPass::runOnPacketFlow(DeviceOp device, OpBuilder &builder, PacketRulesOp packetrules; if (slaveRules.count(slave) == 0) { - packetrules = PacketRulesOp::create(builder, builder.getUnknownLoc(), - bundle, channel); + packetrules = PacketRulesOp::create(builder, tileLoc, bundle, channel); PacketRulesOp::ensureTerminator(packetrules.getRules(), builder, - builder.getUnknownLoc()); + tileLoc); slaveRules[slave] = packetrules; } else packetrules = slaveRules[slave]; @@ -939,7 +937,7 @@ AIEPathfinderPass::runOnPacketFlow(DeviceOp device, OpBuilder &builder, } builder.setInsertionPoint(rules.getTerminator()); - PacketRuleOp::create(builder, builder.getUnknownLoc(), mask, ID, amsel); + PacketRuleOp::create(builder, tileLoc, mask, ID, amsel); } } @@ -996,13 +994,13 @@ AIEPathfinderPass::runOnPacketFlow(DeviceOp device, OpBuilder &builder, pktrules.setSourceBundle(WireBundle::South); if (pktrules.getSourceChannel() == 0) { pktrules.setSourceChannel(3); - ConnectOp::create(builder, builder.getUnknownLoc(), WireBundle::DMA, - 0, WireBundle::North, 3); + ConnectOp::create(builder, tileOp.getLoc(), WireBundle::DMA, 0, + WireBundle::North, 3); } if (pktrules.getSourceChannel() == 1) { pktrules.setSourceChannel(7); - ConnectOp::create(builder, builder.getUnknownLoc(), WireBundle::DMA, - 1, WireBundle::North, 7); + ConnectOp::create(builder, tileOp.getLoc(), WireBundle::DMA, 1, + WireBundle::North, 7); } } } @@ -1027,13 +1025,13 @@ AIEPathfinderPass::runOnPacketFlow(DeviceOp device, OpBuilder &builder, mtset.setDestBundle(WireBundle::South); if (mtset.getDestChannel() == 0) { mtset.setDestChannel(2); - ConnectOp::create(builder, builder.getUnknownLoc(), - WireBundle::North, 2, WireBundle::DMA, 0); + ConnectOp::create(builder, tileOp.getLoc(), WireBundle::North, 2, + WireBundle::DMA, 0); } if (mtset.getDestChannel() == 1) { mtset.setDestChannel(3); - ConnectOp::create(builder, builder.getUnknownLoc(), - WireBundle::North, 3, WireBundle::DMA, 1); + ConnectOp::create(builder, tileOp.getLoc(), WireBundle::North, 3, + WireBundle::DMA, 1); } } } @@ -1084,54 +1082,55 @@ void AIEPathfinderPass::runOnOperation() { sw = analyzer.coordToSwitchbox[{col, row}]; else continue; + Location loc = tile.getLoc(); if (col > 0) { // connections east-west between stream switches if (analyzer.coordToSwitchbox.count({col - 1, row})) { auto westsw = analyzer.coordToSwitchbox[{col - 1, row}]; - WireOp::create(builder, builder.getUnknownLoc(), westsw, - WireBundle::East, sw, WireBundle::West); + WireOp::create(builder, loc, westsw, WireBundle::East, sw, + WireBundle::West); } } if (row > 0) { // connections between abstract 'core' of tile - WireOp::create(builder, builder.getUnknownLoc(), tile, WireBundle::Core, - sw, WireBundle::Core); + WireOp::create(builder, loc, tile, WireBundle::Core, sw, + WireBundle::Core); // connections between abstract 'dma' of tile - WireOp::create(builder, builder.getUnknownLoc(), tile, WireBundle::DMA, - sw, WireBundle::DMA); + WireOp::create(builder, loc, tile, WireBundle::DMA, sw, + WireBundle::DMA); // connections north-south inside array ( including connection to shim // row) if (analyzer.coordToSwitchbox.count({col, row - 1})) { auto southsw = analyzer.coordToSwitchbox[{col, row - 1}]; - WireOp::create(builder, builder.getUnknownLoc(), southsw, - WireBundle::North, sw, WireBundle::South); + WireOp::create(builder, loc, southsw, WireBundle::North, sw, + WireBundle::South); } } else if (row == 0) { if (tile.isShimNOCTile()) { if (analyzer.coordToShimMux.count({col, 0})) { auto shimsw = analyzer.coordToShimMux[{col, 0}]; WireOp::create( - builder, builder.getUnknownLoc(), shimsw, + builder, loc, shimsw, WireBundle::North, // Changed to connect into the north sw, WireBundle::South); // PLIO is attached to shim mux if (analyzer.coordToPLIO.count(col)) { auto plio = analyzer.coordToPLIO[col]; - WireOp::create(builder, builder.getUnknownLoc(), plio, - WireBundle::North, shimsw, WireBundle::South); + WireOp::create(builder, loc, plio, WireBundle::North, shimsw, + WireBundle::South); } // abstract 'DMA' connection on tile is attached to shim mux ( in // row 0 ) - WireOp::create(builder, builder.getUnknownLoc(), tile, - WireBundle::DMA, shimsw, WireBundle::DMA); + WireOp::create(builder, loc, tile, WireBundle::DMA, shimsw, + WireBundle::DMA); } } else if (tile.isShimPLTile()) { // PLIO is attached directly to switch if (analyzer.coordToPLIO.count(col)) { auto plio = analyzer.coordToPLIO[col]; - WireOp::create(builder, builder.getUnknownLoc(), plio, - WireBundle::North, sw, WireBundle::South); + WireOp::create(builder, loc, plio, WireBundle::North, sw, + WireBundle::South); } } } diff --git a/lib/Dialect/AIE/Transforms/AIEGenerateColumnControlOverlay.cpp b/lib/Dialect/AIE/Transforms/AIEGenerateColumnControlOverlay.cpp index 59d4f2caaf3..909823ce0a6 100644 --- a/lib/Dialect/AIE/Transforms/AIEGenerateColumnControlOverlay.cpp +++ b/lib/Dialect/AIE/Transforms/AIEGenerateColumnControlOverlay.cpp @@ -201,8 +201,8 @@ struct AIEGenerateColumnControlOverlayPass } } - AIE::PacketFlowOp createPacketFlowOp(OpBuilder &builder, int &flowID, - Value source, + AIE::PacketFlowOp createPacketFlowOp(OpBuilder &builder, Location loc, + int &flowID, Value source, xilinx::AIE::WireBundle sourceBundle, uint32_t sourceChannel, Value dest, xilinx::AIE::WireBundle destBundle, @@ -211,17 +211,15 @@ struct AIEGenerateColumnControlOverlayPass mlir::BoolAttr ctrl_pkt_flow = nullptr) { OpBuilder::InsertionGuard guard(builder); - AIE::PacketFlowOp pktFlow = - AIE::PacketFlowOp::create(builder, builder.getUnknownLoc(), flowID++, - keep_pkt_header, ctrl_pkt_flow); + AIE::PacketFlowOp pktFlow = AIE::PacketFlowOp::create( + builder, loc, flowID++, keep_pkt_header, ctrl_pkt_flow); Region &r_pktFlow = pktFlow.getPorts(); Block *b_pktFlow = builder.createBlock(&r_pktFlow); builder.setInsertionPointToStart(b_pktFlow); - AIE::PacketSourceOp::create(builder, builder.getUnknownLoc(), source, - sourceBundle, sourceChannel); - AIE::PacketDestOp::create(builder, builder.getUnknownLoc(), dest, - destBundle, destChannel); - AIE::EndOp::create(builder, builder.getUnknownLoc()); + AIE::PacketSourceOp::create(builder, loc, source, sourceBundle, + sourceChannel); + AIE::PacketDestOp::create(builder, loc, dest, destBundle, destChannel); + AIE::EndOp::create(builder, loc); return pktFlow; } @@ -299,14 +297,14 @@ struct AIEGenerateColumnControlOverlayPass auto ctrl_pkt_flow = builder.getBoolAttr(true); if (isShimMM2S) (void)createPacketFlowOp( - builder, ctrlPktFlowID, shimTile, shimWireBundle, + builder, tOp.getLoc(), ctrlPktFlowID, shimTile, shimWireBundle, rowToShimChanMap[tOp.rowIndex()], tOp, ctrlWireBundle, coreOrMemChanId, keep_pkt_header, ctrl_pkt_flow); else - (void)createPacketFlowOp(builder, ctrlPktFlowID, tOp, ctrlWireBundle, - coreOrMemChanId, shimTile, shimWireBundle, - rowToShimChanMap[tOp.rowIndex()], - keep_pkt_header, ctrl_pkt_flow); + (void)createPacketFlowOp( + builder, tOp.getLoc(), ctrlPktFlowID, tOp, ctrlWireBundle, + coreOrMemChanId, shimTile, shimWireBundle, + rowToShimChanMap[tOp.rowIndex()], keep_pkt_header, ctrl_pkt_flow); // Generate shim dma alloc ops as handle for runtime sequence to pickup, // when issuing control packets @@ -327,9 +325,8 @@ struct AIEGenerateColumnControlOverlayPass continue; AIE::ShimDMAAllocationOp::create( - builder, builder.getUnknownLoc(), StringRef(dma_name), - shimTile.getResult(), dir, rowToShimChanMap[tOp.rowIndex()], false, - nullptr); + builder, tOp.getLoc(), StringRef(dma_name), shimTile.getResult(), dir, + rowToShimChanMap[tOp.rowIndex()], false, nullptr); } } diff --git a/lib/Dialect/AIE/Transforms/AIELocalizeLocks.cpp b/lib/Dialect/AIE/Transforms/AIELocalizeLocks.cpp index 9627496c4c3..457f2734365 100644 --- a/lib/Dialect/AIE/Transforms/AIELocalizeLocks.cpp +++ b/lib/Dialect/AIE/Transforms/AIELocalizeLocks.cpp @@ -80,7 +80,7 @@ struct AIELocalizeLocksPass OpBuilder::atBlockBegin(&coreOp.getBody().front()); Value coreLockIDValue = arith::ConstantIndexOp::create( - builder, builder.getUnknownLoc(), localLockIndex); + builder, lock.getLoc(), localLockIndex); lock.getResult().replaceUsesWithIf( coreLockIDValue, [&](OpOperand &opOperand) { return opOperand.getOwner()->getParentOp() == coreOp; diff --git a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp index 4ef0bbc73a4..a8bd3732214 100644 --- a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp +++ b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp @@ -79,7 +79,7 @@ struct AIELowerCascadeFlowsPass } else { outputDir = WireBundle::South; } - ConfigureCascadeOp::create(builder, builder.getUnknownLoc(), tile, + ConfigureCascadeOp::create(builder, tile.getLoc(), tile, static_cast(inputDir), static_cast(outputDir)); } diff --git a/lib/Dialect/AIE/Transforms/AIEObjectFifoRegisterProcess.cpp b/lib/Dialect/AIE/Transforms/AIEObjectFifoRegisterProcess.cpp index a304954b898..31800d9cd6a 100644 --- a/lib/Dialect/AIE/Transforms/AIEObjectFifoRegisterProcess.cpp +++ b/lib/Dialect/AIE/Transforms/AIEObjectFifoRegisterProcess.cpp @@ -42,15 +42,15 @@ struct AIEObjectFifoRegisterProcessPass : xilinx::AIE::impl::AIEObjectFifoRegisterProcessBase< AIEObjectFifoRegisterProcessPass> { - scf::ForOp createForLoop(OpBuilder &builder, int length) { - auto lowerBound = arith::ConstantOp::create( - builder, builder.getUnknownLoc(), builder.getIndexAttr(0)); - auto upperBound = arith::ConstantOp::create( - builder, builder.getUnknownLoc(), builder.getIndexAttr(length)); - auto step = arith::ConstantOp::create(builder, builder.getUnknownLoc(), - builder.getIndexAttr(1)); - auto forLoop = scf::ForOp::create(builder, builder.getUnknownLoc(), - lowerBound, upperBound, step); + scf::ForOp createForLoop(OpBuilder &builder, Location loc, int length) { + auto lowerBound = + arith::ConstantOp::create(builder, loc, builder.getIndexAttr(0)); + auto upperBound = + arith::ConstantOp::create(builder, loc, builder.getIndexAttr(length)); + auto step = + arith::ConstantOp::create(builder, loc, builder.getIndexAttr(1)); + auto forLoop = + scf::ForOp::create(builder, loc, lowerBound, upperBound, step); return forLoop; } @@ -58,10 +58,11 @@ struct AIEObjectFifoRegisterProcessPass ObjectFifoRegisterProcessOp regOp, MemRefType elementType, IntegerAttr acqNumber, IntegerAttr relNumber, int length) { auto ctx = device->getContext(); + Location loc = regOp.getLoc(); // create for loop scf::ForOp forLoop; if (length > 1) { - forLoop = createForLoop(builder, length); + forLoop = createForLoop(builder, loc, length); Region &forRegion = forLoop.getRegion(); builder.setInsertionPointToStart(&forRegion.back()); } @@ -70,13 +71,13 @@ struct AIEObjectFifoRegisterProcessPass if (acqNumber.getInt() > 0) { auto acqType = AIEObjectFifoSubviewType::get(elementType); auto acqOp = ObjectFifoAcquireOp::create( - builder, builder.getUnknownLoc(), acqType, regOp.getPortAttr(), + builder, loc, acqType, regOp.getPortAttr(), SymbolRefAttr::get(ctx, regOp.getObjFifoName()), acqNumber); // subview accesses for (int i = 0; i < acqNumber.getInt(); i++) (void)ObjectFifoSubviewAccessOp::create( - builder, builder.getUnknownLoc(), elementType, acqOp.getSubview(), + builder, loc, elementType, acqOp.getSubview(), builder.getIntegerAttr(builder.getI32Type(), i)); // apply kernel @@ -87,14 +88,13 @@ struct AIEObjectFifoRegisterProcessPass break; } } - func::CallOp::create(builder, builder.getUnknownLoc(), - func /*, acc.output()*/); + func::CallOp::create(builder, loc, func /*, acc.output()*/); } // releases if (relNumber.getInt() > 0) { auto relOp = ObjectFifoReleaseOp::create( - builder, builder.getUnknownLoc(), regOp.getPortAttr(), + builder, loc, regOp.getPortAttr(), SymbolRefAttr::get(ctx, regOp.getObjFifoName()), relNumber); builder.setInsertionPointAfter(relOp); } @@ -143,13 +143,13 @@ struct AIEObjectFifoRegisterProcessPass /*AllowRepeats=*/false); // retrieve core associated to above tile or create new one if (!op) { - CoreOp coreOp = CoreOp::create(builder, builder.getUnknownLoc(), + CoreOp coreOp = CoreOp::create(builder, registerOp.getLoc(), builder.getIndexType(), tile); Region &r = coreOp.getBody(); r.push_back(new Block); Block &block = r.back(); builder.setInsertionPointToStart(&block); - EndOp::create(builder, builder.getUnknownLoc()); + EndOp::create(builder, registerOp.getLoc()); builder.setInsertionPointToStart(&block); } else { CoreOp coreOp = llvm::dyn_cast(op); diff --git a/lib/Dialect/AIE/Transforms/AIEObjectFifoStatefulTransform.cpp b/lib/Dialect/AIE/Transforms/AIEObjectFifoStatefulTransform.cpp index a3f7f6234bf..4ff90e79851 100644 --- a/lib/Dialect/AIE/Transforms/AIEObjectFifoStatefulTransform.cpp +++ b/lib/Dialect/AIE/Transforms/AIEObjectFifoStatefulTransform.cpp @@ -375,14 +375,14 @@ struct AIEObjectFifoStatefulTransformPass } ObjectFifoCreateOp - createObjectFifo(OpBuilder &builder, AIEObjectFifoType datatype, + createObjectFifo(OpBuilder &builder, Location loc, AIEObjectFifoType datatype, std::string name, Value prodTile, Value consTile, Attribute depth, BDDimLayoutArrayAttr dimensionsToStream, BDDimLayoutArrayArrayAttr dimensionsFromStreamPerConsumer) { auto ofName = builder.getStringAttr(name); auto fifo = ObjectFifoCreateOp::create( - builder, builder.getUnknownLoc(), ofName, prodTile, consTile, depth, - datatype, dimensionsToStream, dimensionsFromStreamPerConsumer); + builder, loc, ofName, prodTile, consTile, depth, datatype, + dimensionsToStream, dimensionsFromStreamPerConsumer); return fifo; } @@ -411,14 +411,15 @@ struct AIEObjectFifoStatefulTransformPass if (!state.externalBuffersPerFifo[op].empty()) numElem = state.externalBuffersPerFifo[op].size(); } + Location ofLoc = op.getLoc(); if (target.getTargetArch() == AIEArch::AIE1) { for (int i = 0; i < numElem; i++) { // create corresponding aie1 locks int initValue = op.getInitValues().has_value() ? 1 : 0; int lockID = lockAnalysis.getLockID(creation_tile); assert(lockID >= 0 && "No more locks to allocate!"); - auto lock = LockOp::create(builder, builder.getUnknownLoc(), - creation_tile, lockID, initValue); + auto lock = + LockOp::create(builder, ofLoc, creation_tile, lockID, initValue); lock.getOperation()->setAttr(SymbolTable::getSymbolAttrName(), builder.getStringAttr(op.name().str() + "_lock_" + @@ -434,9 +435,8 @@ struct AIEObjectFifoStatefulTransformPass int prodLockID = lockAnalysis.getLockID(creation_tile); assert(prodLockID >= 0 && "No more locks to allocate!"); int prodLockValue = (numElem - initValues) * repeatCount; - auto prodLock = - LockOp::create(builder, builder.getUnknownLoc(), creation_tile, - prodLockID, prodLockValue); + auto prodLock = LockOp::create(builder, ofLoc, creation_tile, + prodLockID, prodLockValue); prodLock.getOperation()->setAttr( SymbolTable::getSymbolAttrName(), builder.getStringAttr(op.name().str() + "_prod_lock_" + @@ -446,9 +446,8 @@ struct AIEObjectFifoStatefulTransformPass int consLockID = lockAnalysis.getLockID(creation_tile); assert(consLockID >= 0 && "No more locks to allocate!"); int consLockValue = initValues * repeatCount; - auto consLock = - LockOp::create(builder, builder.getUnknownLoc(), creation_tile, - consLockID, consLockValue); + auto consLock = LockOp::create(builder, ofLoc, creation_tile, + consLockID, consLockValue); consLock.getOperation()->setAttr( SymbolTable::getSymbolAttrName(), builder.getStringAttr(op.name().str() + "_cons_lock_" + @@ -580,7 +579,7 @@ struct AIEObjectFifoStatefulTransformPass } builder.setInsertionPointAfter(insertAfter); - auto newTile = TileOp::create(builder, builder.getUnknownLoc(), col, row); + auto newTile = TileOp::create(builder, hostTile.getLoc(), col, row); builder.restoreInsertionPoint(savedInsertionPoint); @@ -774,8 +773,7 @@ struct AIEObjectFifoStatefulTransformPass } } auto buff = BufferOp::create( - builder, builder.getUnknownLoc(), elemType, - current_buf_allocation_tile, + builder, op.getLoc(), elemType, current_buf_allocation_tile, builder.getStringAttr(op.name().str() + "_buff_" + std::to_string(of_elem_index)), /*address*/ nullptr, initValues, @@ -817,31 +815,27 @@ struct AIEObjectFifoStatefulTransformPass /// Function used to create a Bd block. template - void createBd(OpBuilder &builder, LockOp acqLock, int acqMode, + void createBd(OpBuilder &builder, Location loc, LockOp acqLock, int acqMode, LockAction acqLockAction, LockOp relLock, int relMode, MyOp buff, int offset, int len, Block *succ, BDDimLayoutArrayAttr dims, BDPadLayoutArrayAttr padDimensions, std::optional bdPacket) { if (acqLock) - UseLockOp::create(builder, builder.getUnknownLoc(), acqLock, - acqLockAction, acqMode); + UseLockOp::create(builder, loc, acqLock, acqLockAction, acqMode); if (bdPacket) { - DMABDPACKETOp::create(builder, builder.getUnknownLoc(), - bdPacket->getPktType(), bdPacket->getPktId()); + DMABDPACKETOp::create(builder, loc, bdPacket->getPktType(), + bdPacket->getPktId()); } if (!dims.getValue().empty() && padDimensions) { - DMABDOp::create(builder, builder.getUnknownLoc(), buff, offset, len, dims, - padDimensions); + DMABDOp::create(builder, loc, buff, offset, len, dims, padDimensions); } else if (!dims.getValue().empty()) { - DMABDOp::create(builder, builder.getUnknownLoc(), buff, offset, len, - dims); + DMABDOp::create(builder, loc, buff, offset, len, dims); } else { - DMABDOp::create(builder, builder.getUnknownLoc(), buff, offset, len); + DMABDOp::create(builder, loc, buff, offset, len); } if (acqLock) - UseLockOp::create(builder, builder.getUnknownLoc(), relLock, - LockAction::Release, relMode); - NextBDOp::create(builder, builder.getUnknownLoc(), succ); + UseLockOp::create(builder, loc, relLock, LockAction::Release, relMode); + NextBDOp::create(builder, loc, succ); } /// Function used to create a Bd block. @@ -886,8 +880,8 @@ struct AIEObjectFifoStatefulTransformPass : state.locksPerFifo[op][prodLockIndex]; } } - createBd(builder, acqLock, acqMode, acqLockAction, relLock, relMode, buff, - offset, len, succ, dims, padDimensions, bdPacket); + createBd(builder, op.getLoc(), acqLock, acqMode, acqLockAction, relLock, + relMode, buff, offset, len, succ, dims, padDimensions, bdPacket); } /// Function that either calls createAIETileDMA(), createShimDMA() or @@ -965,12 +959,11 @@ struct AIEObjectFifoStatefulTransformPass if (producerMem == nullptr) { OpBuilder::InsertionGuard g(builder); builder.setInsertionPoint(device.getBody()->getTerminator()); - auto newMemOp = - MemOp::create(builder, builder.getUnknownLoc(), objFifoTileOp); + auto newMemOp = MemOp::create(builder, op.getLoc(), objFifoTileOp); { OpBuilder::InsertionGuard g(builder); builder.setInsertionPointToStart(&newMemOp.getRegion().emplaceBlock()); - EndOp::create(builder, builder.getUnknownLoc()); + EndOp::create(builder, op.getLoc()); } producerMem = newMemOp.getOperation(); } @@ -986,8 +979,8 @@ struct AIEObjectFifoStatefulTransformPass int dmaRepeatCount = useHwRepeat ? repeatCount - 1 : 0; int bdRepeatCount = useHwRepeat ? 1 : repeatCount; builder.setInsertionPointToStart(dmaBlock); - DMAStartOp::create(builder, builder.getUnknownLoc(), channelDir, - channelIndex, dmaRepeatCount, bdBlock, endBlock); + DMAStartOp::create(builder, op.getLoc(), channelDir, channelIndex, + dmaRepeatCount, bdBlock, endBlock); if (lastDmaBlock != nullptr) lastDmaBlock->getTerminator()->setSuccessor(dmaBlock, 1); @@ -1045,12 +1038,12 @@ struct AIEObjectFifoStatefulTransformPass if (producerDMA == nullptr) { OpBuilder::InsertionGuard g(builder); builder.setInsertionPoint(device.getBody()->getTerminator()); - auto newDMAOp = ShimDMAOp::create(builder, builder.getUnknownLoc(), + auto newDMAOp = ShimDMAOp::create(builder, op.getLoc(), builder.getIndexType(), objFifoTileOp); { OpBuilder::InsertionGuard g(builder); builder.setInsertionPointToStart(&newDMAOp.getRegion().emplaceBlock()); - EndOp::create(builder, builder.getUnknownLoc()); + EndOp::create(builder, op.getLoc()); } producerDMA = newDMAOp.getOperation(); } @@ -1062,8 +1055,8 @@ struct AIEObjectFifoStatefulTransformPass // create DMA channel builder.setInsertionPointToStart(dmaBlock); - DMAStartOp::create(builder, builder.getUnknownLoc(), channelDir, - channelIndex, /*repeatCout*/ 0, bdBlock, endBlock); + DMAStartOp::create(builder, op.getLoc(), channelDir, channelIndex, + /*repeatCout*/ 0, bdBlock, endBlock); if (lastDmaBlock != nullptr) lastDmaBlock->getTerminator()->setSuccessor(dmaBlock, 1); @@ -1208,12 +1201,11 @@ struct AIEObjectFifoStatefulTransformPass if (producerDMA == nullptr) { OpBuilder::InsertionGuard g(builder); builder.setInsertionPoint(device.getBody()->getTerminator()); - auto newDMAOp = - MemTileDMAOp::create(builder, builder.getUnknownLoc(), objFifoTileOp); + auto newDMAOp = MemTileDMAOp::create(builder, op.getLoc(), objFifoTileOp); { OpBuilder::InsertionGuard g(builder); builder.setInsertionPointToStart(&newDMAOp.getRegion().emplaceBlock()); - EndOp::create(builder, builder.getUnknownLoc()); + EndOp::create(builder, op.getLoc()); } producerDMA = newDMAOp.getOperation(); } @@ -1239,8 +1231,8 @@ struct AIEObjectFifoStatefulTransformPass if (useHwRepeat) taskCount = repeatCount - 1; int bdRepeatFactor = useHwRepeat ? 1 : repeatCount; - DMAStartOp::create(builder, builder.getUnknownLoc(), channelDir, - channelIndex, taskCount, bdBlock, endBlock); + DMAStartOp::create(builder, op.getLoc(), channelDir, channelIndex, + taskCount, bdBlock, endBlock); if (lastDmaBlock != nullptr) lastDmaBlock->getTerminator()->setSuccessor(dmaBlock, 1); @@ -1264,7 +1256,7 @@ struct AIEObjectFifoStatefulTransformPass // Create a separate terminating block with aie.end for this // specific DMA channel builder.setInsertionPointToStart(succ); - EndOp::create(builder, builder.getUnknownLoc()); + EndOp::create(builder, op.getLoc()); } else { succ = bdBlock; } @@ -1431,9 +1423,9 @@ struct AIEObjectFifoStatefulTransformPass BufferOp globalNextIndex, arith::ConstantOp index, arith::ConstantOp size) { builder.setInsertionPointAfter(relOp); - Value oldCounter = memref::LoadOp::create( - builder, builder.getUnknownLoc(), globalNextIndex, - ValueRange(ArrayRef({index.getResult()}))); + Value oldCounter = + memref::LoadOp::create(builder, relOp.getLoc(), globalNextIndex, + ValueRange(ArrayRef({index.getResult()}))); Value val = arith::ConstantOp::create(builder, oldCounter.getLoc(), builder.getI32IntegerAttr(relOp.getSize())); @@ -1473,8 +1465,8 @@ struct AIEObjectFifoStatefulTransformPass int index = 0; builder.setInsertionPointToStart(&(coreOp.getBody().front())); - Value initVal = arith::ConstantOp::create( - builder, builder.getUnknownLoc(), builder.getI32IntegerAttr(0)); + Value initVal = arith::ConstantOp::create(builder, coreOp.getLoc(), + builder.getI32IntegerAttr(0)); coreOp.walk([&](ObjectFifoAcquireOp acqOp) { ObjectFifoCreateOp op = acqOp.getObjectFifo(); ObjectFifoPort port = acqOp.getPort(); @@ -1495,7 +1487,7 @@ struct AIEObjectFifoStatefulTransformPass MemRefType::get(SmallVector{(int64_t)fifoSizes.size()}, builder.getI32Type()); auto globalNextIndex = BufferOp::create( - builder, builder.getUnknownLoc(), memrefTy, coreOp.getTile(), + builder, coreOp.getLoc(), memrefTy, coreOp.getTile(), /*sym_name*/ nullptr, /*address*/ nullptr, /*initial_value*/ nullptr, /*mem_bank*/ nullptr, /*aligned*/ nullptr); @@ -1504,7 +1496,7 @@ struct AIEObjectFifoStatefulTransformPass for (auto i : constantSizes) { builder.setInsertionPointAfter(i.second); memref::StoreOp::create( - builder, builder.getUnknownLoc(), initVal, globalNextIndex, + builder, coreOp.getLoc(), initVal, globalNextIndex, ValueRange(ArrayRef({globalIndices[i.first].getResult()}))); } @@ -1539,11 +1531,11 @@ struct AIEObjectFifoStatefulTransformPass // Create a switch for each subview access builder.setInsertionPointAfter(accessOp); auto switchIndexAsInteger = memref::LoadOp::create( - builder, builder.getUnknownLoc(), globalNextIndex, + builder, acqOp.getLoc(), globalNextIndex, ValueRange( ArrayRef({globalIndices[{createOp, port}].getResult()}))); auto switchIndex = arith::IndexCastOp::create( - builder, builder.getUnknownLoc(), builder.getIndexType(), + builder, acqOp.getLoc(), builder.getIndexType(), switchIndexAsInteger); unsigned caseRegionCounts = fifoSizes[{createOp, port}]; SmallVector caseValues; @@ -1561,7 +1553,7 @@ struct AIEObjectFifoStatefulTransformPass auto bufferIndex = (accessOp.getIndex()) % createOp.size(); builder.setInsertionPointToStart(&(switchOp.getDefaultBlock())); scf::YieldOp::create( - builder, builder.getUnknownLoc(), + builder, accessOp.getLoc(), state.buffersPerFifo[createOp][bufferIndex].getResult()); for (int i = 0; i < fifoSizes[{createOp, port}]; ++i) { // Create other cases of IndexSwitchOp @@ -1625,7 +1617,7 @@ struct AIEObjectFifoStatefulTransformPass lockMode = 1; for (int i = 0; i < numLocks; i++) { int lockID = acc[{op, portNum}]; - UseLockOp::create(builder, builder.getUnknownLoc(), + UseLockOp::create(builder, op.getLoc(), state.locksPerFifo[target][lockID], lockAction, lockMode); acc[{op, portNum}] = @@ -1655,8 +1647,7 @@ struct AIEObjectFifoStatefulTransformPass else lock = state.locksPerFifo[target][0]; } - UseLockOp::create(builder, builder.getUnknownLoc(), lock, lockAction, - numLocks); + UseLockOp::create(builder, op.getLoc(), lock, lockAction, numLocks); acc[{op, portNum}] = (acc[{op, portNum}] + numLocks) % op.size(); // update to next objFifo elem } @@ -1768,7 +1759,7 @@ struct AIEObjectFifoStatefulTransformPass std::string alloc_name = getShimAllocationName(objFifoOp.getName()); // SymbolRefAttr::get(ctx, objFifoOp.getName()) ShimDMAAllocationOp::create( - builder, builder.getUnknownLoc(), StringAttr::get(ctx, alloc_name), + builder, objFifoOp.getLoc(), StringAttr::get(ctx, alloc_name), shimTile.getResult(), DMAChannelDirAttr::get(ctx, channelDir), builder.getI64IntegerAttr(channelIndex), builder.getBoolAttr(plio), packetInfo); @@ -1930,9 +1921,10 @@ struct AIEObjectFifoStatefulTransformPass BDDimLayoutArrayArrayAttr::get(builder.getContext(), singletonFromStreamDims); - ObjectFifoCreateOp consumerFifo = createObjectFifo( - builder, datatype, consumerFifoName, consumerTile, consumerTile, - consumerObjFifoSize, emptyDims, fromStreamDims); + ObjectFifoCreateOp consumerFifo = + createObjectFifo(builder, createOp.getLoc(), datatype, + consumerFifoName, consumerTile, consumerTile, + consumerObjFifoSize, emptyDims, fromStreamDims); if (createOp.getDisableSynchronization()) consumerFifo.setDisableSynchronization(true); // Propagate iter_count attribute from the original createOp @@ -2095,14 +2087,14 @@ struct AIEObjectFifoStatefulTransformPass // create packet flow builder.setInsertionPointAfter(producer); packetflow = builder.create( - builder.getUnknownLoc(), + producer.getLoc(), builder.getIntegerAttr(builder.getI8Type(), bdPacket->getPktId()), nullptr, nullptr); { OpBuilder::InsertionGuard g(builder); builder.setInsertionPointToStart( &packetflow.getRegion().emplaceBlock()); - builder.create(builder.getUnknownLoc()); + builder.create(producer.getLoc()); } } } @@ -2146,7 +2138,7 @@ struct AIEObjectFifoStatefulTransformPass if (clPacketSwObjectFifos) { builder.setInsertionPointToStart(&packetflow.getPorts().front()); - builder.create(builder.getUnknownLoc(), + builder.create(consumer.getLoc(), consumer.getProducerTile(), WireBundle::DMA, consumerChan.channel); } @@ -2178,16 +2170,16 @@ struct AIEObjectFifoStatefulTransformPass if (!clPacketSwObjectFifos) { // create flow builder.setInsertionPointAfter(producer); - FlowOp::create(builder, builder.getUnknownLoc(), - producer.getProducerTile(), producerWireType, - producerChan.channel, consumer.getProducerTile(), - consumerWireType, consumerChan.channel); + FlowOp::create(builder, producer.getLoc(), producer.getProducerTile(), + producerWireType, producerChan.channel, + consumer.getProducerTile(), consumerWireType, + consumerChan.channel); } } if (clPacketSwObjectFifos) { builder.setInsertionPointToStart(&packetflow.getPorts().front()); - PacketSourceOp::create(builder, builder.getUnknownLoc(), + PacketSourceOp::create(builder, producer.getLoc(), producer.getProducerTile(), WireBundle::DMA, producerChan.channel); } diff --git a/lib/Dialect/AIEX/Transforms/AIECreateBroadcastPacket.cpp b/lib/Dialect/AIEX/Transforms/AIECreateBroadcastPacket.cpp index a981c7728de..53aca85cb3d 100644 --- a/lib/Dialect/AIEX/Transforms/AIECreateBroadcastPacket.cpp +++ b/lib/Dialect/AIEX/Transforms/AIECreateBroadcastPacket.cpp @@ -72,11 +72,11 @@ struct AIEBroadcastPacketPass int flowID = bpid.IDInt(); builder.setInsertionPointAfter(broadcastpacket); PacketFlowOp pkFlow = PacketFlowOp::create( - builder, builder.getUnknownLoc(), flowID, nullptr, nullptr); + builder, broadcastpacket.getLoc(), flowID, nullptr, nullptr); Region &r_pkFlow = pkFlow.getPorts(); Block *b_pkFlow = builder.createBlock(&r_pkFlow); builder.setInsertionPointToStart(b_pkFlow); - PacketSourceOp::create(builder, builder.getUnknownLoc(), srcTile, + PacketSourceOp::create(builder, broadcastpacket.getLoc(), srcTile, sourcePort.bundle, sourcePort.channel); for (Operation &op : b_bpid.getOperations()) { if (BPDestOp bpdest = dyn_cast(op)) { @@ -84,12 +84,12 @@ struct AIEBroadcastPacketPass dyn_cast(bpdest.getTile().getDefiningOp()); Port destPort = bpdest.port(); builder.setInsertionPointToEnd(b_pkFlow); - PacketDestOp::create(builder, builder.getUnknownLoc(), destTile, + PacketDestOp::create(builder, bpdest.getLoc(), destTile, destPort.bundle, destPort.channel); } } builder.setInsertionPointToEnd(b_pkFlow); - EndOp::create(builder, builder.getUnknownLoc()); + EndOp::create(builder, broadcastpacket.getLoc()); } } } diff --git a/lib/Dialect/AIEX/Transforms/AIECreateCores.cpp b/lib/Dialect/AIEX/Transforms/AIECreateCores.cpp index 4d5aa21b4b7..3d79fbc2bc1 100644 --- a/lib/Dialect/AIEX/Transforms/AIECreateCores.cpp +++ b/lib/Dialect/AIEX/Transforms/AIECreateCores.cpp @@ -106,8 +106,8 @@ struct AIECreateCoresPass // get or create TileOp if (!tiles[{colIndex, rowIndex}]) { builder.setInsertionPointToStart(device.getBody()); - TileOp tile = TileOp::create(builder, builder.getUnknownLoc(), colIndex, - rowIndex); + TileOp tile = + TileOp::create(builder, callOp.getLoc(), colIndex, rowIndex); tiles[{colIndex, rowIndex}] = tile; } Operation *tileOp = tiles[{colIndex, rowIndex}]; @@ -130,21 +130,21 @@ struct AIECreateCoresPass assert(t && "Unsupported type!"); coreBufTypes.push_back({t, i}); BufferOp buf = BufferOp::create( - builder, builder.getUnknownLoc(), t, tile, /*sym_name*/ nullptr, + builder, callOp.getLoc(), t, tile, /*sym_name*/ nullptr, /*address*/ nullptr, /*initial_value*/ nullptr, /*mem_bank*/ nullptr, /*aligned*/ nullptr); buffers[callOperands[i]] = buf; operand.replaceAllUsesWith(buf.getResult()); } - MemOp mem = MemOp::create(builder, builder.getUnknownLoc(), + MemOp mem = MemOp::create(builder, callOp.getLoc(), builder.getIndexType(), tile); Region &r = mem.getBody(); Block *endBlock = builder.createBlock(&r); // block terminator builder.setInsertionPointToStart(endBlock); - EndOp::create(builder, builder.getUnknownLoc()); + EndOp::create(builder, callOp.getLoc()); mems[tileOp] = mem; } @@ -163,7 +163,7 @@ struct AIECreateCoresPass Block *currentBlock; if (!cores[tileOp]) { - core = CoreOp::create(builder, builder.getUnknownLoc(), tile); + core = CoreOp::create(builder, callOp.getLoc(), tile); Region &r = core.getBody(); currentBlock = builder.createBlock(&r); builder.setInsertionPointToStart(currentBlock); @@ -187,10 +187,10 @@ struct AIECreateCoresPass assert(pair.first.getShape()[0] == 1 && "Expected MemRefType of single element"); - Value zero = arith::ConstantIndexOp::create( - builder, builder.getUnknownLoc(), 0); - auto loadOp = memref::LoadOp::create( - builder, builder.getUnknownLoc(), arg.getType(), buf, zero); + Value zero = + arith::ConstantIndexOp::create(builder, callOp.getLoc(), 0); + auto loadOp = memref::LoadOp::create(builder, callOp.getLoc(), + arg.getType(), buf, zero); mapper.map(arg, loadOp); } else { mapper.map(arg, buf); @@ -207,7 +207,7 @@ struct AIECreateCoresPass } if (!cores[tileOp]) { // block terminator - EndOp::create(builder, builder.getUnknownLoc()); + EndOp::create(builder, callOp.getLoc()); cores[tileOp] = core; } } @@ -233,7 +233,7 @@ struct AIECreateCoresPass // "Could not allocate more than two dest. channel when creating // FlowOp"); // // WireBundle[1] = DMA - // FlowOp::create(builder, builder.getUnknownLoc(), srcTile, 1, 0, + // FlowOp::create(builder, callOp.getLoc(), srcTile, 1, 0, // dstTile, 1, destChannel[op.dstTile()]); destChannel[op.dstTile()]++; // } diff --git a/lib/Dialect/AIEX/Transforms/AIECreateLocks.cpp b/lib/Dialect/AIEX/Transforms/AIECreateLocks.cpp index 8566a3f48cc..028d837c274 100644 --- a/lib/Dialect/AIEX/Transforms/AIECreateLocks.cpp +++ b/lib/Dialect/AIEX/Transforms/AIECreateLocks.cpp @@ -200,8 +200,7 @@ struct AIECreateLocksPass LLVM_DEBUG(llvm::dbgs() << "Shared tile \n"; tileOp->print(llvm::dbgs())); LLVM_DEBUG(llvm::dbgs() << " LockID: " << lockID << '\n'); builder.setInsertionPointAfter(tileOp); - LockOp lock = - LockOp::create(builder, builder.getUnknownLoc(), tile, lockID, 0); + LockOp lock = LockOp::create(builder, tile.getLoc(), tile, lockID, 0); lockChains[std::make_pair(release, acquire)] = std::make_pair(lock, 1); diff --git a/lib/Dialect/AIEX/Transforms/AIECtrlPacketToDma.cpp b/lib/Dialect/AIEX/Transforms/AIECtrlPacketToDma.cpp index bbe5d6fd31a..72b3227a4f0 100644 --- a/lib/Dialect/AIEX/Transforms/AIECtrlPacketToDma.cpp +++ b/lib/Dialect/AIEX/Transforms/AIECtrlPacketToDma.cpp @@ -192,7 +192,7 @@ struct AIECtrlPacketToDmaPass SymbolRefAttr metadata = SymbolRefAttr::get(builder.getContext(), batchIt->shimDmaAllocName); - NpuDmaMemcpyNdOp::create(builder, builder.getUnknownLoc(), newBlockArg, + NpuDmaMemcpyNdOp::create(builder, loc, newBlockArg, SmallVector{}, SmallVector{}, SmallVector{}, ArrayRef(staticOffsets), ArrayRef(staticSizes), ArrayRef(staticStrides), diff --git a/lib/Dialect/AIEX/Transforms/AIEExpandLoadPdi.cpp b/lib/Dialect/AIEX/Transforms/AIEExpandLoadPdi.cpp index beb68c77304..9fcf85429de 100644 --- a/lib/Dialect/AIEX/Transforms/AIEExpandLoadPdi.cpp +++ b/lib/Dialect/AIEX/Transforms/AIEExpandLoadPdi.cpp @@ -68,7 +68,7 @@ static LogicalResult transformLoadPdi(NpuLoadPdiOp loadPdiOp, ModuleOp moduleOp, AIE::DeviceOp emptyDevice = moduleOp.lookupSymbol(emptyName); if (!emptyDevice) { auto deviceType = referencedDevice.getDevice(); - auto loc = builder.getUnknownLoc(); + auto loc = loadPdiOp.getLoc(); emptyDevice = AIE::DeviceOp::create(builder, loc, deviceType, builder.getStringAttr(emptyName)); emptyDevice.getRegion().emplaceBlock(); diff --git a/lib/Dialect/AIEX/Transforms/AIEHerdRouting.cpp b/lib/Dialect/AIEX/Transforms/AIEHerdRouting.cpp index da549558cfa..b5cdf6c1433 100644 --- a/lib/Dialect/AIEX/Transforms/AIEHerdRouting.cpp +++ b/lib/Dialect/AIEX/Transforms/AIEHerdRouting.cpp @@ -304,15 +304,12 @@ struct AIEHerdRoutingPass builder.setInsertionPoint(device.getBody()->getTerminator()); - auto iterx = - IterOp::create(builder, builder.getUnknownLoc(), x, x + 1, 1); - auto itery = - IterOp::create(builder, builder.getUnknownLoc(), y, y + 1, 1); - auto sel = SelectOp::create(builder, builder.getUnknownLoc(), herd, iterx, - itery); - auto swbox = SwitchboxOp::create(builder, builder.getUnknownLoc(), sel); - SwitchboxOp::ensureTerminator(swbox.getConnections(), builder, - builder.getUnknownLoc()); + Location loc = herdOp->getLoc(); + auto iterx = IterOp::create(builder, loc, x, x + 1, 1); + auto itery = IterOp::create(builder, loc, y, y + 1, 1); + auto sel = SelectOp::create(builder, loc, herd, iterx, itery); + auto swbox = SwitchboxOp::create(builder, loc, sel); + SwitchboxOp::ensureTerminator(swbox.getConnections(), builder, loc); Block &b = swbox.getConnections().front(); builder.setInsertionPoint(b.getTerminator()); @@ -322,8 +319,8 @@ struct AIEHerdRoutingPass WireBundle destBundle = destPort.bundle; int destChannel = destPort.channel; - ConnectOp::create(builder, builder.getUnknownLoc(), sourceBundle, - sourceChannel, destBundle, destChannel); + ConnectOp::create(builder, loc, sourceBundle, sourceChannel, destBundle, + destChannel); } } diff --git a/lib/Dialect/AIEX/Transforms/AIELowerMemcpy.cpp b/lib/Dialect/AIEX/Transforms/AIELowerMemcpy.cpp index 3047dd57eab..01c20cd56ff 100644 --- a/lib/Dialect/AIEX/Transforms/AIELowerMemcpy.cpp +++ b/lib/Dialect/AIEX/Transforms/AIELowerMemcpy.cpp @@ -46,9 +46,10 @@ struct LowerAIEMemcpy : public OpConversionPattern { LowerAIEMemcpy(MLIRContext *context, PatternBenefit benefit = 1) : OpConversionPattern(context, benefit) {} - void createDMABlocksAndOps(MemOp &mem, StringRef tokenName, int acquireTknVal, - int releaseTknVal, Value buf, int offset, int len, - DMAChannelDir dmaDir, int channelIndex, + void createDMABlocksAndOps(MemOp &mem, Location loc, StringRef tokenName, + int acquireTknVal, int releaseTknVal, Value buf, + int offset, int len, DMAChannelDir dmaDir, + int channelIndex, ConversionPatternRewriter &rewriter) const { Region &r = mem.getBody(); @@ -57,7 +58,7 @@ struct LowerAIEMemcpy : public OpConversionPattern { Block *bdBlock = rewriter.createBlock(&endBlock); rewriter.setInsertionPointToStart(dmaBlock); - DMAStartOp::create(rewriter, rewriter.getUnknownLoc(), dmaDir, channelIndex, + DMAStartOp::create(rewriter, loc, dmaDir, channelIndex, /*repeatCount*/ 0, bdBlock, &endBlock); // Setup bd Block @@ -65,12 +66,12 @@ struct LowerAIEMemcpy : public OpConversionPattern { // for specifying DMA Block description (which buffer type (A/B), transfer // length/address, etc.) rewriter.setInsertionPointToStart(bdBlock); - UseTokenOp::create(rewriter, rewriter.getUnknownLoc(), tokenName, - acquireTknVal, LockAction::Acquire); - DMABDOp::create(rewriter, rewriter.getUnknownLoc(), buf, offset, len); - UseTokenOp::create(rewriter, rewriter.getUnknownLoc(), tokenName, - releaseTknVal, LockAction::Release); - NextBDOp::create(rewriter, rewriter.getUnknownLoc(), &endBlock); + UseTokenOp::create(rewriter, loc, tokenName, acquireTknVal, + LockAction::Acquire); + DMABDOp::create(rewriter, loc, buf, offset, len); + UseTokenOp::create(rewriter, loc, tokenName, releaseTknVal, + LockAction::Release); + NextBDOp::create(rewriter, loc, &endBlock); } LogicalResult @@ -90,12 +91,12 @@ struct LowerAIEMemcpy : public OpConversionPattern { MemOp srcMem = srcTileOp(op).getMemOp(); MemOp dstMem = dstTileOp(op).getMemOp(); - createDMABlocksAndOps(srcMem, tokenName, acquireTknVal, releaseTknVal, - srcBuf, srcOffset, srcLen, DMAChannelDir::MM2S, 0, - rewriter); - createDMABlocksAndOps(dstMem, tokenName, acquireTknVal, releaseTknVal, - dstBuf, dstOffset, dstLen, DMAChannelDir::S2MM, 0, - rewriter); + createDMABlocksAndOps(srcMem, op.getLoc(), tokenName, acquireTknVal, + releaseTknVal, srcBuf, srcOffset, srcLen, + DMAChannelDir::MM2S, 0, rewriter); + createDMABlocksAndOps(dstMem, op.getLoc(), tokenName, acquireTknVal, + releaseTknVal, dstBuf, dstOffset, dstLen, + DMAChannelDir::S2MM, 0, rewriter); rewriter.eraseOp(op); return success(); @@ -126,8 +127,8 @@ struct AIELowerMemcpyPass assert(destChannel[op.getDstTile()] <= 2 && "Could not allocate more than two dest. channel when creating " "FlowOp"); - FlowOp::create(builder, builder.getUnknownLoc(), srcTile, WireBundle::DMA, - 0, dstTile, WireBundle::DMA, destChannel[op.getDstTile()]); + FlowOp::create(builder, op.getLoc(), srcTile, WireBundle::DMA, 0, dstTile, + WireBundle::DMA, destChannel[op.getDstTile()]); destChannel[op.getDstTile()]++; } diff --git a/lib/Dialect/AIEX/Transforms/AIELowerMulticast.cpp b/lib/Dialect/AIEX/Transforms/AIELowerMulticast.cpp index e21c1a54843..7cf249913b3 100644 --- a/lib/Dialect/AIEX/Transforms/AIELowerMulticast.cpp +++ b/lib/Dialect/AIEX/Transforms/AIELowerMulticast.cpp @@ -67,7 +67,7 @@ struct AIELowerMulticastPass TileOp destTile = dyn_cast(multiDest.getTile().getDefiningOp()); Port destPort = multiDest.port(); - FlowOp::create(builder, builder.getUnknownLoc(), srcTile, + FlowOp::create(builder, multiDest.getLoc(), srcTile, sourcePort.bundle, sourcePort.channel, destTile, destPort.bundle, destPort.channel); } diff --git a/test/Conversion/AIEToConfiguration/loc_preservation.mlir b/test/Conversion/AIEToConfiguration/loc_preservation.mlir new file mode 100644 index 00000000000..c0d2a36db46 --- /dev/null +++ b/test/Conversion/AIEToConfiguration/loc_preservation.mlir @@ -0,0 +1,31 @@ +//===- loc_preservation.mlir -----------------------*- MLIR -*-===// +// +// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// (c) Copyright 2026 AMD Inc. +// +//===----------------------------------------------------------------------===// + +// Verifies --convert-aie-to-control-packets attaches the source DeviceOp's +// loc to the synthesized aie.runtime_sequence and aiex.control_packet ops. + +// RUN: aie-opt --convert-aie-to-control-packets="elf-dir=%S/convert_aie_to_ctrl_pkts_elfs/" --mlir-print-debuginfo %s | FileCheck %s + +#device_loc = loc("user_design.py":42:4) + +aie.device(npu1_1col) { + %12 = aie.tile(0, 2) + %buf = aie.buffer(%12) : memref<256xi32> + %4 = aie.core(%12) { + aie.end + } { elf_file = "core_0_2.elf" } +} loc(#device_loc) + +// At least one synthesized aiex.control_packet inside the new +// runtime_sequence carries the device's loc, and the runtime_sequence +// itself does too. (The pass creates the runtime_sequence on demand.) +// CHECK-DAG: aie.runtime_sequence @configure() {{[{][[:space:]]*$}} +// CHECK-DAG: aiex.control_packet {{.*}} loc(#[[DEVLOC:loc[0-9]*]]) +// CHECK-DAG: #[[DEVLOC]] = loc("user_design.py":42:4) diff --git a/test/aiecc/cpp_ctrlpkt.mlir b/test/aiecc/cpp_ctrlpkt.mlir index d19659f5329..dfeb6d683ff 100644 --- a/test/aiecc/cpp_ctrlpkt.mlir +++ b/test/aiecc/cpp_ctrlpkt.mlir @@ -12,7 +12,9 @@ // Preprocess with overlay (matching ctrl_packet_reconfig test flow) // RUN: aie-opt -aie-generate-column-control-overlay="route-shim-to-tile-ctrl=true" %s -o %t_overlay.mlir -// RUN: aiecc --no-xchesscc --no-xbridge --aie-generate-ctrlpkt --verbose %t_overlay.mlir 2>&1 | FileCheck %s +// RUN: aiecc --no-xchesscc --no-xbridge --aie-generate-ctrlpkt --dump-intermediates --tmpdir=%t_ctrlpkt_tmp --verbose %t_overlay.mlir 2>&1 | FileCheck %s +// RUN: FileCheck %s --check-prefix=DUMP < %t_ctrlpkt_tmp/main_ctrlpkt.mlir +// RUN: FileCheck %s --check-prefix=DUMP < %t_ctrlpkt_tmp/input_with_addresses.mlir // CHECK: Generating control packets for device // CHECK: Running control packet pipeline in-memory @@ -21,6 +23,8 @@ // CHECK: Wrote {{[0-9]+}} DMA sequence instructions to // CHECK: Compilation completed successfully +// DUMP: loc( + module { aie.device(npu1) { %tile_0_0 = aie.tile(0, 0) diff --git a/test/create-cores/loc_preservation.mlir b/test/create-cores/loc_preservation.mlir new file mode 100644 index 00000000000..1b5d55ca268 --- /dev/null +++ b/test/create-cores/loc_preservation.mlir @@ -0,0 +1,74 @@ +//===- loc_preservation.mlir -----------------------*- MLIR -*-===// +// +// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// (c) Copyright 2026 AMD Inc. +// +//===----------------------------------------------------------------------===// + +// Verifies that: +// - --aie-create-cores forwards the source func.call op's location to the +// synthesized aie.tile / aie.buffer / aie.mem / aie.core / aie.end ops. +// - --aie-lower-memcpy forwards the source aiex.memcpy op's location to +// the synthesized aie.flow / aie.dma_start / aie.dma_bd / aiex.useToken +// / aie.next_bd ops. + +// RUN: aie-opt --aie-create-cores --aie-lower-memcpy --mlir-print-debuginfo %s | FileCheck %s + +#call_loc = loc("user_design.py":42:4) +#memcpy_loc = loc("user_design.py":50:4) + +module @loc_test { + aie.device(xcvc1902) { + %t11 = aie.tile(1, 1) + %t22 = aie.tile(2, 2) + + %buf0 = memref.alloc() : memref<256xi32> + %buf1 = memref.alloc() : memref<256xi32> + %buf2 = memref.alloc() : memref<256xi32> + + aiex.token(0) { sym_name = "token0" } + + func.func @task0(%arg0: memref<256xi32>) -> () { + aiex.useToken @token0(Acquire, 0) + aiex.useToken @token0(Release, 1) + return + } + func.func @task1(%arg0: memref<256xi32>) -> () { + aiex.useToken @token0(Acquire, 2) + aiex.useToken @token0(Release, 3) + return + } + func.func @task2(%arg0: memref<256xi32>) -> () { + return + } + + func.call @task0(%buf0) { aie.x = 1, aie.y = 1 } : (memref<256xi32>) -> () loc(#call_loc) + aiex.memcpy @token0(1, 2) (%t11 : <%buf0, 0, 256>, %t22 : <%buf1, 0, 256>) : (memref<256xi32>, memref<256xi32>) loc(#memcpy_loc) + func.call @task1(%buf1) { aie.x = 2, aie.y = 2 } : (memref<256xi32>) -> () + func.call @task2(%buf2) { aie.x = 3, aie.y = 3 } : (memref<256xi32>) -> () loc(#call_loc) + } +} + +// AIECreateCores: synthesized tile / core / end / mem / buffer for the call +// op carry +// the call's loc. +// CHECK-DAG: aie.tile(3, 3) loc(#[[CALLLOC:loc[0-9]*]]) +// CHECK-DAG: aie.mem({{.*}}) +// CHECK-DAG: aie.core({{.*}}) {{[{][[:space:]]*$}} +// CHECK-DAG: aie.end loc(#[[CALLLOC]]) +// CHECK-DAG: } loc(#[[CALLLOC]]) +// CHECK-DAG: aie.buffer({{.*}}) : memref<256xi32> loc(#[[CALLLOC]]) + +// AIELowerMemcpy: synthesized aie.flow / dma_start / dma_bd / use_token / +// next_bd carry the memcpy's loc. +// CHECK-DAG: aie.flow({{.*}}) loc(#[[MCLOC:loc[0-9]*]]) +// CHECK-DAG: aie.dma_start({{.*}}) loc(#[[MCLOC]]) +// CHECK-DAG: aie.dma_bd({{.*}}) loc(#[[MCLOC]]) +// CHECK-DAG: aie.next_bd {{.*}} loc(#[[MCLOC]]) +// CHECK-DAG: aiex.useToken {{.*}} loc(#[[MCLOC]]) + +// CHECK-DAG: #[[CALLLOC]] = loc("user_design.py":42:4) +// CHECK-DAG: #[[MCLOC]] = loc("user_design.py":50:4) diff --git a/test/create-flows/loc_preservation.mlir b/test/create-flows/loc_preservation.mlir new file mode 100644 index 00000000000..44071ff3709 --- /dev/null +++ b/test/create-flows/loc_preservation.mlir @@ -0,0 +1,33 @@ +//===- loc_preservation.mlir -----------------------*- MLIR -*-===// +// +// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// (c) Copyright 2026 AMD Inc. +// +//===----------------------------------------------------------------------===// + +// Verifies --aie-create-pathfinder-flows propagates the source FlowOp's +// location to the synthesized ConnectOps inside switchboxes, and that +// per-tile WireOps inherit the corresponding tile's location. + +// RUN: aie-opt --aie-create-pathfinder-flows --mlir-print-debuginfo %s | FileCheck %s + +#flow_loc = loc("user_design.py":42:4) +#tile_loc = loc("user_design.py":50:8) + +module { + aie.device(xcvc1902) { + %0 = aie.tile(2, 3) loc(#tile_loc) + %1 = aie.tile(3, 2) loc(#tile_loc) + aie.flow(%0, Core : 1, %1, DMA : 0) loc(#flow_loc) + } +} + +// Synthesized aie.connect ops inside switchboxes carry the FlowOp's loc. +// CHECK-DAG: aie.connect<{{.*}}> loc(#[[FLOWLOC:loc[0-9]*]]) +// Synthesized aie.wire ops between switchboxes/tiles carry the tile's loc. +// CHECK-DAG: aie.wire({{.*}}) loc(#[[TILELOC:loc[0-9]*]]) +// CHECK-DAG: #[[FLOWLOC]] = loc("user_design.py":42:4) +// CHECK-DAG: #[[TILELOC]] = loc("user_design.py":50:8) diff --git a/test/herd-routing/loc_preservation.mlir b/test/herd-routing/loc_preservation.mlir new file mode 100644 index 00000000000..277af54c326 --- /dev/null +++ b/test/herd-routing/loc_preservation.mlir @@ -0,0 +1,46 @@ +//===- loc_preservation.mlir -----------------------*- MLIR -*-===// +// +// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// (c) Copyright 2026 AMD Inc. +// +//===----------------------------------------------------------------------===// + +// Verifies --aie-herd-routing forwards the source HerdOp's location onto +// the synthesized iter / select / switchbox / connect ops produced when +// expanding a route. + +// The herd-routing pass produces an IR shape that the verifier rejects under +// the current placement model (aie.switchbox expects a placed tile). The +// location forwarding under test is independent of that — disable the +// after-pass verifier so we can inspect the synthesized ops. + +// RUN: aie-opt --verify-each=false --aie-herd-routing --mlir-print-debuginfo %s | FileCheck %s + +#herd_loc = loc("user_design.py":42:4) + +// Use distinct, non-default locs on the user-written ops (iter, select) so +// the test can isolate the locs that --aie-herd-routing synthesizes from +// the pre-existing user-written ones. +#scaffold_loc = loc("scaffold.mlir":1:1) + +module @loc_test { + aie.device(xcvc1902) { + %t = aiex.herd[1][1] { sym_name = "t" } loc(#herd_loc) + %s = aiex.herd[1][1] { sym_name = "s" } loc(#herd_loc) + + %i0 = aiex.iter(0, 1, 1) loc(#scaffold_loc) + + %sel_t = aiex.select(%t, %i0, %i0) loc(#scaffold_loc) + %sel_s = aiex.select(%s, %i0, %i0) loc(#scaffold_loc) + aiex.place(%t, %s, 3, 3) loc(#scaffold_loc) + aiex.route(<%sel_t, DMA: 0>, <%sel_s, DMA: 0>) loc(#scaffold_loc) + } +} + +// Synthesized aie.connect ops (only present after the pass) inherit the +// herd's source loc rather than loc(unknown) or the scaffold loc. +// CHECK-DAG: "aie.connect"() {{.*}} loc(#[[HERDLOC:loc[0-9]*]]) +// CHECK-DAG: #[[HERDLOC]] = loc("user_design.py":42:4) diff --git a/test/lower-to-standard/loc_preservation.mlir b/test/lower-to-standard/loc_preservation.mlir new file mode 100644 index 00000000000..e5bba596498 --- /dev/null +++ b/test/lower-to-standard/loc_preservation.mlir @@ -0,0 +1,42 @@ +//===- loc_preservation.mlir -----------------------*- MLIR -*-===// +// +// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// (c) Copyright 2026 AMD Inc. +// +//===----------------------------------------------------------------------===// + +// Verifies that --aie-standard-lowering forwards the source op's location +// onto its lowered standard-dialect ops. + +// RUN: aie-opt --aie-localize-locks --aie-standard-lowering --mlir-print-debuginfo %s | FileCheck %s + +#user_loc = loc("user_design.py":42:4) +#buf_loc = loc("user_design.py":50:4) + +module @loc_test { + aie.device(xcve2302) { + %tile13 = aie.tile(1, 3) + %lock13 = aie.lock(%tile13, 0) loc(#user_loc) + %buf13 = aie.buffer(%tile13) {sym_name = "my_buf"} : memref<16xi32> loc(#buf_loc) + + func.func private @kernel(%lock : index) { + aie.use_lock(%lock, "Acquire", 0) loc(#user_loc) + return + } + + %core13 = aie.core(%tile13) { + func.call @kernel(%lock13) : (index) -> () + aie.end + } + } +} + +// The lowered call to llvm.aie2.acquire and the memref.global for the +// buffer must reference the user's source location, not loc(unknown). +// CHECK-DAG: call @llvm.aie2.acquire({{.*}}) : (i32, i32) -> () loc(#[[ULOC:loc[0-9]*]]) +// CHECK-DAG: memref.global "public" @my_buf : memref<16xi32> loc(#[[BUFLOC:loc[0-9]*]]) +// CHECK-DAG: #[[ULOC]] = loc("user_design.py":42:4) +// CHECK-DAG: #[[BUFLOC]] = loc("user_design.py":50:4) diff --git a/test/objectFifo-stateful-transform/base/loc_preservation.mlir b/test/objectFifo-stateful-transform/base/loc_preservation.mlir new file mode 100644 index 00000000000..8dfa032592e --- /dev/null +++ b/test/objectFifo-stateful-transform/base/loc_preservation.mlir @@ -0,0 +1,36 @@ +//===- loc_preservation.mlir ------------------------*- MLIR -*-===// +// +// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// (c) Copyright 2026 AMD Inc. +// +//===----------------------------------------------------------------------===// + +// Verifies that --aie-objectFifo-stateful-transform forwards the source +// objectfifo.create op's Location onto the synthesized buffer / lock ops. +// See docs/SourceLocations.md for the broader plan. + +// RUN: aie-opt --aie-objectFifo-stateful-transform --mlir-print-debuginfo %s | FileCheck %s + +#user_loc = loc("user_design.py":42:4) + +module @loc_test { + aie.device(xcve2302) { + %tile12 = aie.tile(1, 2) loc(unknown) + %tile13 = aie.tile(1, 3) loc(unknown) + aie.objectfifo @of0 (%tile12, {%tile13}, 4 : i32) : !aie.objectfifo> loc(#user_loc) + } +} + +// MLIR pretty-prints with location aliases (loc(#locN)) at the end of the +// module. Capture the alias used on the source objectfifo, then assert that +// the synthesized buffers / locks reference the same alias and that the +// alias resolves to user_design.py:42:4 (and is *not* loc(unknown)). + +// CHECK: aie.buffer({{.*}}) {sym_name = "of0_buff_0"} : memref<16xi32>{{ +}}loc(#[[USERLOC:loc[0-9]*]]) +// CHECK: aie.buffer({{.*}}) {sym_name = "of0_buff_1"} : memref<16xi32>{{ +}}loc(#[[USERLOC]]) +// CHECK: aie.lock({{.*}}) {init = 4 : i32, sym_name = "of0_prod_lock_0"} loc(#[[USERLOC]]) +// CHECK: aie.lock({{.*}}) {init = 0 : i32, sym_name = "of0_cons_lock_0"} loc(#[[USERLOC]]) +// CHECK: #[[USERLOC]] = loc("user_design.py":42:4) diff --git a/tools/aiecc/aiecc.cpp b/tools/aiecc/aiecc.cpp index 2897b95bab3..aa1ddcbefeb 100644 --- a/tools/aiecc/aiecc.cpp +++ b/tools/aiecc/aiecc.cpp @@ -28,6 +28,7 @@ #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/Diagnostics.h" #include "mlir/IR/MLIRContext.h" +#include "mlir/IR/OperationSupport.h" #include "mlir/InitAllDialects.h" #include "mlir/InitAllExtensions.h" #include "mlir/InitAllPasses.h" @@ -528,6 +529,12 @@ static std::vector getHostSourceFiles() { return hostFiles; } +static void printModuleWithDebugInfo(ModuleOp moduleOp, raw_ostream &os) { + OpPrintingFlags flags; + flags.enableDebugInfo(/*enable=*/true); + moduleOp->print(os, flags); +} + /// Dump an MLIR module to a file if --dump-intermediates is enabled. /// Returns true on success, false on failure. static bool dumpModuleToFile(ModuleOp moduleOp, StringRef filePath, @@ -542,7 +549,7 @@ static bool dumpModuleToFile(ModuleOp moduleOp, StringRef filePath, << filePath << ": " << ec.message() << "\n"; return false; } - moduleOp->print(file); + printModuleWithDebugInfo(moduleOp, file); file.close(); if (verbose) { @@ -5231,7 +5238,11 @@ static LogicalResult compileAIEModule(MLIRContext &context, ModuleOp moduleOp, << "\n"; return failure(); } - moduleOp->print(file); + if (dumpIntermediates) { + printModuleWithDebugInfo(moduleOp, file); + } else { + moduleOp->print(file); + } if (verbose) { llvm::outs() << "Wrote module with addresses to: " << withAddressesPath