Skip to content

Commit f9fd968

Browse files
committed
Forward source locations across AIE/AIEX transform passes
Replace builder.getUnknownLoc() with the source op's location at op- creation sites across the AIE and AIEX transform passes, so that ops synthesized during lowering inherit a useful Location instead of "unknown". This is purely mechanical: every replacement uses the loc of the op being lowered (or a contextually-appropriate parent op such as the surrounding tile, device, or originating flow). Passes updated: AIEObjectFifoStatefulTransform AIECreateBroadcastPacket AIECoreToStandard AIECreateCores AIECreatePathFindFlows AIECreateLocks AIEObjectFifoRegisterProcess AIECtrlPacketToDma AIEGenerateColumnControlOverlay AIEExpandLoadPdi AIECanonicalizeDevice AIEHerdRouting AIELocalizeLocks AIELowerMemcpy AIELowerCascadeFlows AIELowerMulticast AIEDialect (TileOp helper) AIEToConfiguration The few remaining getUnknownLoc() sites (declareAIEIntrinsics, DynamicTileAnalysis helpers, parsed-binary ModuleOp creation) have no source op to attribute and are left alone intentionally. Adds one focused loc_preservation.mlir lit test per converted pass to guard against regression: test/Conversion/AIEToConfiguration/loc_preservation.mlir test/create-cores/loc_preservation.mlir test/create-flows/loc_preservation.mlir test/herd-routing/loc_preservation.mlir test/lower-to-standard/loc_preservation.mlir test/objectFifo-stateful-transform/base/loc_preservation.mlir
1 parent 9796296 commit f9fd968

24 files changed

Lines changed: 456 additions & 227 deletions

lib/Conversion/AIEToConfiguration/AIEToConfiguration.cpp

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -450,12 +450,10 @@ static LogicalResult generateTransactions(AIERTControl &ctl,
450450
// Translate vector of TransactionBinaryOperation to a sequence of transaction
451451
// ops (npu.write32, npu.maskwrite32, npu.blockwrite).
452452
static LogicalResult
453-
emitTransactionOps(OpBuilder &builder,
453+
emitTransactionOps(OpBuilder &builder, Location loc,
454454
std::vector<TransactionBinaryOperation> &operations,
455455
std::vector<memref::GlobalOp> &global_data) {
456456

457-
auto loc = builder.getUnknownLoc();
458-
459457
// create the txn ops
460458
for (auto [op, payload] : llvm::zip(operations, global_data)) {
461459

@@ -531,11 +529,10 @@ emitTransactionOps(OpBuilder &builder,
531529
// Translate vector of TransactionBinaryOperation to a sequence of control
532530
// packet ops.
533531
static LogicalResult
534-
emitControlPacketOps(OpBuilder &builder,
532+
emitControlPacketOps(OpBuilder &builder, Location loc,
535533
std::vector<TransactionBinaryOperation> &operations,
536534
std::vector<memref::GlobalOp> &global_data) {
537535

538-
auto loc = builder.getUnknownLoc();
539536
auto ctx = builder.getContext();
540537

541538
// create the control packet ops
@@ -636,17 +633,15 @@ static LogicalResult convertTransactionOpsToMLIR(
636633
std::vector<TransactionBinaryOperation> &operations,
637634
std::string blockwrite_prefix = "config_blockwrite_data_") {
638635

639-
auto loc = builder.getUnknownLoc();
640-
641636
// for each blockwrite in the binary, create a GlobalOp with the data at the
642637
// device level
643638
std::vector<memref::GlobalOp> global_data;
639+
DeviceOp device = llvm::dyn_cast<DeviceOp>(builder.getBlock()->getParentOp());
640+
if (!device) {
641+
device = builder.getBlock()->getParentOp()->getParentOfType<DeviceOp>();
642+
}
643+
Location loc = device.getLoc();
644644
{
645-
DeviceOp device =
646-
llvm::dyn_cast<DeviceOp>(builder.getBlock()->getParentOp());
647-
if (!device) {
648-
device = builder.getBlock()->getParentOp()->getParentOfType<DeviceOp>();
649-
}
650645
OpBuilder::InsertionGuard guard(builder);
651646
builder.setInsertionPointToStart(device.getBody());
652647
int id = 0;
@@ -676,10 +671,10 @@ static LogicalResult convertTransactionOpsToMLIR(
676671

677672
// create the txn ops
678673
if (outputType == AIE::AIEToConfigurationOutputType::Transaction) {
679-
if (failed(emitTransactionOps(builder, operations, global_data)))
674+
if (failed(emitTransactionOps(builder, loc, operations, global_data)))
680675
return failure();
681676
} else if (outputType == AIE::AIEToConfigurationOutputType::ControlPacket) {
682-
if (failed(emitControlPacketOps(builder, operations, global_data)))
677+
if (failed(emitControlPacketOps(builder, loc, operations, global_data)))
683678
return failure();
684679
// resolve mask writes; control packet doesn't natively support mask write.
685680
if (failed(orConsecutiveWritesOnSameAddr(builder.getBlock())))
@@ -784,7 +779,7 @@ convertAIEToConfiguration(AIE::DeviceOp device, StringRef clElfDir,
784779
// and collect them in a vector. If there are none, create a new runtime
785780
// sequence. Otherwise assume the insertion point is the first
786781
// aiex.configure op.
787-
auto loc = builder.getUnknownLoc();
782+
auto loc = device.getLoc();
788783
SmallVector<AIEX::ConfigureOp> configureOps;
789784
device.walk([&](AIEX::ConfigureOp op) { configureOps.push_back(op); });
790785

lib/Dialect/AIE/IR/AIEDialect.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1600,8 +1600,8 @@ TileOp TileOp::getOrCreate(mlir::OpBuilder builder, DeviceOp device, int col,
16001600
OpBuilder::InsertionGuard guard(builder);
16011601
mlir::Block &device_start_block = *device.getBodyRegion().begin();
16021602
builder.setInsertionPointToStart(&device_start_block);
1603-
tile = TileOp::create(builder, builder.getUnknownLoc(),
1604-
builder.getIndexType(), col, row);
1603+
tile = TileOp::create(builder, device.getLoc(), builder.getIndexType(), col,
1604+
row);
16051605
}
16061606
return tile;
16071607
}

lib/Dialect/AIE/Transforms/AIECanonicalizeDevice.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ struct AIECanonicalizeDevicePass
4242
// the new op quite yet.
4343
OpBuilder builder(moduleOp->getContext());
4444

45-
Location location = builder.getUnknownLoc();
45+
Location location = moduleOp.getLoc();
4646
auto deviceOp = DeviceOp::create(
4747
builder, location,
4848
AIEDeviceAttr::get(builder.getContext(), AIEDevice::xcvc1902),

lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ struct AIEDebugOpToStdLowering : OpConversionPattern<DebugOp> {
211211
<< funcName;
212212
SmallVector<Value, 1> args;
213213
args.push_back(op.getArg());
214-
func::CallOp::create(rewriter, rewriter.getUnknownLoc(), func, args);
214+
func::CallOp::create(rewriter, op.getLoc(), func, args);
215215
rewriter.eraseOp(op);
216216
return success();
217217
}
@@ -259,7 +259,7 @@ struct AIEPutStreamToStdLowering : OpConversionPattern<PutStreamOp> {
259259
rewriter, op.getLoc(), IntegerType::get(rewriter.getContext(), 32),
260260
rewriter.getI32IntegerAttr(0))); // tlast
261261
}
262-
func::CallOp::create(rewriter, rewriter.getUnknownLoc(), putMSFunc, args);
262+
func::CallOp::create(rewriter, op.getLoc(), putMSFunc, args);
263263
rewriter.eraseOp(op);
264264
return success();
265265
}
@@ -300,8 +300,8 @@ struct AIEGetStreamToStdLowering : OpConversionPattern<GetStreamOp> {
300300
SmallVector<Value, 2> args;
301301
if (targetModel.getTargetArch() == AIEArch::AIE1)
302302
args.push_back(op.getChannel());
303-
auto getSSCall = func::CallOp::create(rewriter, rewriter.getUnknownLoc(),
304-
getSSFunc, args);
303+
auto getSSCall =
304+
func::CallOp::create(rewriter, op.getLoc(), getSSFunc, args);
305305
rewriter.replaceOp(op, getSSCall.getResult(0));
306306
// Capture TLAST in AIEv2?
307307
return success();
@@ -352,7 +352,7 @@ struct AIEPutCascadeToStdLowering : OpConversionPattern<PutCascadeOp> {
352352
rewriter, op.getLoc(), IntegerType::get(rewriter.getContext(), 32),
353353
rewriter.getI32IntegerAttr(1))); // enable
354354

355-
func::CallOp::create(rewriter, rewriter.getUnknownLoc(), putMCDFunc, args);
355+
func::CallOp::create(rewriter, op.getLoc(), putMCDFunc, args);
356356
rewriter.eraseOp(op);
357357
return success();
358358
}
@@ -388,8 +388,8 @@ struct AIEGetCascadeToStdLowering : OpConversionPattern<GetCascadeOp> {
388388
rewriter, op.getLoc(), IntegerType::get(rewriter.getContext(), 32),
389389
rewriter.getI32IntegerAttr(1))); // enable
390390

391-
auto getSCDCall = func::CallOp::create(rewriter, rewriter.getUnknownLoc(),
392-
getSCDFunc, args);
391+
auto getSCDCall =
392+
func::CallOp::create(rewriter, op.getLoc(), getSCDFunc, args);
393393
Value result = getSCDCall.getResult(0);
394394

395395
// Check if we need a bitcast
@@ -459,8 +459,7 @@ struct AIEUseLockToStdLowering : OpConversionPattern<UseLockOp> {
459459
IntegerType::get(rewriter.getContext(), 32),
460460
rewriter.getI32IntegerAttr(lockValue)));
461461

462-
func::CallOp::create(rewriter, rewriter.getUnknownLoc(), useLockFunc,
463-
args);
462+
func::CallOp::create(rewriter, useLock.getLoc(), useLockFunc, args);
464463
}
465464
rewriter.eraseOp(useLock);
466465
return success();
@@ -490,19 +489,19 @@ struct AIEBufferToStandard : OpConversionPattern<BufferOp> {
490489
// prevent duplication in the data section of the elf/object file)
491490
if ((tileRow != row && tileRow != -1) || (tileCol != col && tileCol != -1))
492491
initValue = nullptr;
493-
memref::GlobalOp::create(rewriter, rewriter.getUnknownLoc(), symName,
492+
memref::GlobalOp::create(rewriter, buffer.getLoc(), symName,
494493
rewriter.getStringAttr("public"), buffer.getType(),
495494
initValue, /*constant*/ false,
496495
/*alignment*/ nullptr);
497496

498497
for (auto &use : make_early_inc_range(buffer.getResult().getUses())) {
499498
Operation *user = use.getOwner();
500499
rewriter.setInsertionPoint(user);
501-
auto allocated = memref::GetGlobalOp::create(
502-
rewriter, rewriter.getUnknownLoc(), t, symName);
500+
auto allocated =
501+
memref::GetGlobalOp::create(rewriter, buffer.getLoc(), t, symName);
503502
// Assume that buffers are aligned so they can be vectorized.
504-
memref::AssumeAlignmentOp::create(rewriter, rewriter.getUnknownLoc(),
505-
allocated, 32);
503+
memref::AssumeAlignmentOp::create(rewriter, buffer.getLoc(), allocated,
504+
32);
506505

507506
use.set(allocated.getResult());
508507
}
@@ -547,7 +546,7 @@ struct AIECoreToStandardFunc : OpConversionPattern<CoreOp> {
547546
std::string coreName("core_" + std::to_string(col) + "_" +
548547
std::to_string(row));
549548
auto coreFunc =
550-
func::FuncOp::create(rewriter, rewriter.getUnknownLoc(), coreName,
549+
func::FuncOp::create(rewriter, op.getLoc(), coreName,
551550
FunctionType::get(rewriter.getContext(), {}, {}));
552551

553552
rewriter.cloneRegionBefore(op.getBody(), coreFunc.getBody(),
@@ -641,8 +640,7 @@ struct AIECoreToStandardFunc : OpConversionPattern<CoreOp> {
641640
rewriter.setInsertionPointAfter(childOp);
642641

643642
if (isa<EndOp>(childOp)) {
644-
func::ReturnOp::create(rewriter, rewriter.getUnknownLoc(),
645-
ValueRange({}));
643+
func::ReturnOp::create(rewriter, childOp->getLoc(), ValueRange({}));
646644
rewriter.eraseOp(childOp);
647645
}
648646
});
@@ -701,7 +699,7 @@ struct AIEEventOpToStdLowering : OpConversionPattern<EventOp> {
701699
if (!eventFunc)
702700
return op.emitOpError("Could not find the intrinsic function ")
703701
<< funcName;
704-
func::CallOp::create(rewriter, rewriter.getUnknownLoc(), eventFunc, args);
702+
func::CallOp::create(rewriter, op.getLoc(), eventFunc, args);
705703
rewriter.eraseOp(op);
706704
return success();
707705
}

lib/Dialect/AIE/Transforms/AIECreatePathFindFlows.cpp

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ struct ConvertFlowsToInterconnect : OpConversionPattern<FlowOp> {
4646
auto point = rewriter.saveInsertionPoint();
4747
rewriter.setInsertionPoint(b.getTerminator());
4848

49-
ConnectOp::create(rewriter, rewriter.getUnknownLoc(), inBundle, inIndex,
50-
outBundle, outIndex);
49+
ConnectOp::create(rewriter, flowOp.getLoc(), inBundle, inIndex, outBundle,
50+
outIndex);
5151

5252
rewriter.restoreInsertionPoint(point);
5353

@@ -832,13 +832,13 @@ AIEPathfinderPass::runOnPacketFlow(DeviceOp device, OpBuilder &builder,
832832
Operation *tileOp = map.second;
833833
TileOp tile = cast<TileOp>(map.second);
834834
TileID tileId = tile.getTileID();
835+
Location tileLoc = tile.getLoc();
835836

836837
// Create a switchbox for the routes and insert inside it.
837838
builder.setInsertionPointAfter(tileOp);
838839
SwitchboxOp swbox =
839840
analyzer.getSwitchbox(builder, tile.colIndex(), tile.rowIndex());
840-
SwitchboxOp::ensureTerminator(swbox.getConnections(), builder,
841-
builder.getUnknownLoc());
841+
SwitchboxOp::ensureTerminator(swbox.getConnections(), builder, tileLoc);
842842
Block &b = swbox.getConnections().front();
843843
builder.setInsertionPoint(b.getTerminator());
844844

@@ -859,8 +859,7 @@ AIEPathfinderPass::runOnPacketFlow(DeviceOp device, OpBuilder &builder,
859859
if (amselOpNeededVector[amselValue]) {
860860
int arbiterID = a;
861861
int msel = i;
862-
auto amsel = AMSelOp::create(builder, builder.getUnknownLoc(),
863-
arbiterID, msel);
862+
auto amsel = AMSelOp::create(builder, tileLoc, arbiterID, msel);
864863
amselOps[amselValue] = amsel;
865864
}
866865
}
@@ -885,8 +884,8 @@ AIEPathfinderPass::runOnPacketFlow(DeviceOp device, OpBuilder &builder,
885884
amsels.push_back(amselOps[msel]);
886885
}
887886

888-
MasterSetOp::create(builder, builder.getUnknownLoc(),
889-
builder.getIndexType(), bundle, channel, amsels,
887+
MasterSetOp::create(builder, tileLoc, builder.getIndexType(), bundle,
888+
channel, amsels,
890889
keepPktHeaderAttr[{tileId, tileMaster}]);
891890
}
892891

@@ -915,10 +914,9 @@ AIEPathfinderPass::runOnPacketFlow(DeviceOp device, OpBuilder &builder,
915914

916915
PacketRulesOp packetrules;
917916
if (slaveRules.count(slave) == 0) {
918-
packetrules = PacketRulesOp::create(builder, builder.getUnknownLoc(),
919-
bundle, channel);
917+
packetrules = PacketRulesOp::create(builder, tileLoc, bundle, channel);
920918
PacketRulesOp::ensureTerminator(packetrules.getRules(), builder,
921-
builder.getUnknownLoc());
919+
tileLoc);
922920
slaveRules[slave] = packetrules;
923921
} else
924922
packetrules = slaveRules[slave];
@@ -939,7 +937,7 @@ AIEPathfinderPass::runOnPacketFlow(DeviceOp device, OpBuilder &builder,
939937
}
940938

941939
builder.setInsertionPoint(rules.getTerminator());
942-
PacketRuleOp::create(builder, builder.getUnknownLoc(), mask, ID, amsel);
940+
PacketRuleOp::create(builder, tileLoc, mask, ID, amsel);
943941
}
944942
}
945943

@@ -996,13 +994,13 @@ AIEPathfinderPass::runOnPacketFlow(DeviceOp device, OpBuilder &builder,
996994
pktrules.setSourceBundle(WireBundle::South);
997995
if (pktrules.getSourceChannel() == 0) {
998996
pktrules.setSourceChannel(3);
999-
ConnectOp::create(builder, builder.getUnknownLoc(), WireBundle::DMA,
1000-
0, WireBundle::North, 3);
997+
ConnectOp::create(builder, tileOp.getLoc(), WireBundle::DMA, 0,
998+
WireBundle::North, 3);
1001999
}
10021000
if (pktrules.getSourceChannel() == 1) {
10031001
pktrules.setSourceChannel(7);
1004-
ConnectOp::create(builder, builder.getUnknownLoc(), WireBundle::DMA,
1005-
1, WireBundle::North, 7);
1002+
ConnectOp::create(builder, tileOp.getLoc(), WireBundle::DMA, 1,
1003+
WireBundle::North, 7);
10061004
}
10071005
}
10081006
}
@@ -1027,13 +1025,13 @@ AIEPathfinderPass::runOnPacketFlow(DeviceOp device, OpBuilder &builder,
10271025
mtset.setDestBundle(WireBundle::South);
10281026
if (mtset.getDestChannel() == 0) {
10291027
mtset.setDestChannel(2);
1030-
ConnectOp::create(builder, builder.getUnknownLoc(),
1031-
WireBundle::North, 2, WireBundle::DMA, 0);
1028+
ConnectOp::create(builder, tileOp.getLoc(), WireBundle::North, 2,
1029+
WireBundle::DMA, 0);
10321030
}
10331031
if (mtset.getDestChannel() == 1) {
10341032
mtset.setDestChannel(3);
1035-
ConnectOp::create(builder, builder.getUnknownLoc(),
1036-
WireBundle::North, 3, WireBundle::DMA, 1);
1033+
ConnectOp::create(builder, tileOp.getLoc(), WireBundle::North, 3,
1034+
WireBundle::DMA, 1);
10371035
}
10381036
}
10391037
}
@@ -1084,54 +1082,55 @@ void AIEPathfinderPass::runOnOperation() {
10841082
sw = analyzer.coordToSwitchbox[{col, row}];
10851083
else
10861084
continue;
1085+
Location loc = tile.getLoc();
10871086
if (col > 0) {
10881087
// connections east-west between stream switches
10891088
if (analyzer.coordToSwitchbox.count({col - 1, row})) {
10901089
auto westsw = analyzer.coordToSwitchbox[{col - 1, row}];
1091-
WireOp::create(builder, builder.getUnknownLoc(), westsw,
1092-
WireBundle::East, sw, WireBundle::West);
1090+
WireOp::create(builder, loc, westsw, WireBundle::East, sw,
1091+
WireBundle::West);
10931092
}
10941093
}
10951094
if (row > 0) {
10961095
// connections between abstract 'core' of tile
1097-
WireOp::create(builder, builder.getUnknownLoc(), tile, WireBundle::Core,
1098-
sw, WireBundle::Core);
1096+
WireOp::create(builder, loc, tile, WireBundle::Core, sw,
1097+
WireBundle::Core);
10991098
// connections between abstract 'dma' of tile
1100-
WireOp::create(builder, builder.getUnknownLoc(), tile, WireBundle::DMA,
1101-
sw, WireBundle::DMA);
1099+
WireOp::create(builder, loc, tile, WireBundle::DMA, sw,
1100+
WireBundle::DMA);
11021101
// connections north-south inside array ( including connection to shim
11031102
// row)
11041103
if (analyzer.coordToSwitchbox.count({col, row - 1})) {
11051104
auto southsw = analyzer.coordToSwitchbox[{col, row - 1}];
1106-
WireOp::create(builder, builder.getUnknownLoc(), southsw,
1107-
WireBundle::North, sw, WireBundle::South);
1105+
WireOp::create(builder, loc, southsw, WireBundle::North, sw,
1106+
WireBundle::South);
11081107
}
11091108
} else if (row == 0) {
11101109
if (tile.isShimNOCTile()) {
11111110
if (analyzer.coordToShimMux.count({col, 0})) {
11121111
auto shimsw = analyzer.coordToShimMux[{col, 0}];
11131112
WireOp::create(
1114-
builder, builder.getUnknownLoc(), shimsw,
1113+
builder, loc, shimsw,
11151114
WireBundle::North, // Changed to connect into the north
11161115
sw, WireBundle::South);
11171116
// PLIO is attached to shim mux
11181117
if (analyzer.coordToPLIO.count(col)) {
11191118
auto plio = analyzer.coordToPLIO[col];
1120-
WireOp::create(builder, builder.getUnknownLoc(), plio,
1121-
WireBundle::North, shimsw, WireBundle::South);
1119+
WireOp::create(builder, loc, plio, WireBundle::North, shimsw,
1120+
WireBundle::South);
11221121
}
11231122

11241123
// abstract 'DMA' connection on tile is attached to shim mux ( in
11251124
// row 0 )
1126-
WireOp::create(builder, builder.getUnknownLoc(), tile,
1127-
WireBundle::DMA, shimsw, WireBundle::DMA);
1125+
WireOp::create(builder, loc, tile, WireBundle::DMA, shimsw,
1126+
WireBundle::DMA);
11281127
}
11291128
} else if (tile.isShimPLTile()) {
11301129
// PLIO is attached directly to switch
11311130
if (analyzer.coordToPLIO.count(col)) {
11321131
auto plio = analyzer.coordToPLIO[col];
1133-
WireOp::create(builder, builder.getUnknownLoc(), plio,
1134-
WireBundle::North, sw, WireBundle::South);
1132+
WireOp::create(builder, loc, plio, WireBundle::North, sw,
1133+
WireBundle::South);
11351134
}
11361135
}
11371136
}

0 commit comments

Comments
 (0)