14#include "mlir/Dialect/Arith/IR/Arith.h"
15#include "mlir/IR/Attributes.h"
16#include "mlir/Pass/Pass.h"
19#define GEN_PASS_DEF_AIEXINLINETRACECONFIG
20#include "aie/Dialect/AIEX/Transforms/AIEXPasses.h.inc"
30struct AIEInlineTraceConfigPass
31 : xilinx::AIEX::impl::AIEXInlineTraceConfigBase<AIEInlineTraceConfigPass> {
32 void runOnOperation()
override {
33 AIE::DeviceOp device = getOperation();
34 const auto &targetModel = device.getTargetModel();
37 SmallVector<TraceStartConfigOp> startConfigs;
38 device.walk([&](TraceStartConfigOp startConfig) {
39 startConfigs.push_back(startConfig);
42 for (
auto startConfig : startConfigs) {
43 OpBuilder builder(startConfig);
46 auto configSymbolName = startConfig.getTraceConfig();
48 dyn_cast_or_null<TraceConfigOp>(SymbolTable::lookupNearestSymbolFrom(
49 device, builder.getStringAttr(configSymbolName)));
52 startConfig.emitError(
"trace config symbol '")
53 << configSymbolName <<
"' not found";
54 return signalPassFailure();
58 auto tile = configOp.getTile();
59 auto tileOp = dyn_cast<TileOp>(tile.getDefiningOp());
61 startConfig.emitError(
"tile operand must be a TileOp");
62 return signalPassFailure();
65 int col = tileOp.getCol();
66 int row = tileOp.getRow();
67 TileID tileID = {col, row};
71 if (
auto packetType = configOp.getPacketType()) {
72 isMem = (*packetType == TracePacketType::Mem);
76 for (
auto &op : configOp.getBody().getOps()) {
77 auto regOp = dyn_cast<TraceRegOp>(op);
82 if (regOp.getField()) {
83 regOp.emitError(
"aie.trace.reg still has field attribute - run "
84 "-aie-trace-pack-reg-writes pass first");
85 return signalPassFailure();
89 auto regName = regOp.getRegName().str();
90 const RegisterInfo *regInfo =
91 targetModel.lookupRegister(regName, tileID, isMem);
93 regOp.emitError(
"Register '") << regName <<
"' not found for tile ("
94 << col <<
", " << row <<
")";
95 return signalPassFailure();
100 if (
auto intAttr = llvm::dyn_cast<IntegerAttr>(regOp.getValue())) {
101 value = intAttr.getInt();
103 regOp.emitError(
"value must be an integer after packing");
104 return signalPassFailure();
108 AIEX::NpuWrite32Op::create(
109 builder, regOp.getLoc(),
113 builder.getI32IntegerAttr(col),
114 builder.getI32IntegerAttr(row)
126std::unique_ptr<OperationPass<AIE::DeviceOp>>
128 return std::make_unique<AIEInlineTraceConfigPass>();
std::unique_ptr< mlir::OperationPass< AIE::DeviceOp > > createAIEXInlineTraceConfigPass()
mlir::Value createConstantI32(mlir::OpBuilder &builder, mlir::Location loc, uint32_t value)
struct TileID { friend std::ostream &operator<<(std::ostream &os, const TileID &s) { os<< "TileID("<< s.col<< ", "<< s.row<< ")"; return os; } friend std::string to_string(const TileID &s) { std::ostringstream ss; ss<< s; return ss.str(); } friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const TileID &s) { os<< to_string(s); return os; } inline bool operator<(const TileID &rhs) const { return std::tie(col, row)< std::tie(rhs.col, rhs.row); } bool operator==(const TileID &rhs) const { return std::tie(col, row)==std::tie(rhs.col, rhs.row); } bool operator!=(const TileID &rhs) const { return !(*this==rhs);} int col, row;} TileID