88
99#include " aie/Dialect/AIE/IR/AIEDialect.h"
1010
11+ #include " mlir/Dialect/Arith/IR/Arith.h"
1112#include " mlir/Dialect/Func/IR/FuncOps.h"
1213#include " mlir/Dialect/MemRef/IR/MemRef.h"
1314#include " mlir/IR/DialectImplementation.h"
15+ #include " mlir/IR/Matchers.h"
1416#include " mlir/IR/OpDefinition.h"
1517#include " mlir/IR/SymbolTable.h"
1618#include " mlir/Interfaces/FoldInterfaces.h"
@@ -73,7 +75,11 @@ struct AIEDialectFoldInterface : DialectFoldInterface {
7375 // them with a core's identical constants, which would leave the core
7476 // referencing a device-level value that is erased when the core is
7577 // outlined.
76- return isa<CoreOp, RuntimeSequenceOp>(region->getParentOp ());
78+ // - Make sure SSA values for aie.use_lock operands in
79+ // aie.mem/aie.memtile_dma/aie.shim_dma bodies do not get
80+ // hoisted.
81+ return isa<CoreOp, RuntimeSequenceOp, MemOp, MemTileDMAOp, ShimDMAOp>(
82+ region->getParentOp ());
7783 }
7884};
7985
@@ -2679,6 +2685,15 @@ LogicalResult LockOp::verify() {
26792685 return success ();
26802686}
26812687
2688+ // Look up for compile-time constant lock values, if any.
2689+ // Returns std::nullopt if lock value does not reference an `arith.constant`.
2690+ static std::optional<int32_t > getConstantLockValue (UseLockOp op) {
2691+ if (auto constant = op.getValue ().getDefiningOp <arith::ConstantOp>())
2692+ if (auto intAttr = llvm::dyn_cast<IntegerAttr>(constant.getValue ()))
2693+ return (int32_t )intAttr.getInt ();
2694+ return std::nullopt ;
2695+ }
2696+
26822697struct UsesOneLockInDMABlock {
26832698 static LogicalResult verifyTrait (Operation *op) {
26842699 auto *block = op->getBlock ();
@@ -2700,16 +2715,21 @@ struct AcquireReleaseOneStateInDMABlock {
27002715 auto *block = op->getBlock ();
27012716 int acqValue = -1 , relValue = -1 ;
27022717 for (auto op : block->getOps <UseLockOp>()) {
2718+ // Non-constant lock values cannot be compared here; the passes that
2719+ // require a constant enforce that separately via getConstantValue().
2720+ auto value = getConstantLockValue (op);
2721+ if (!value)
2722+ continue ;
27032723 if (op.acquire () || op.acquireGE ()) {
2704- if (acqValue != -1 && acqValue != op. getLockValue () ) {
2724+ if (acqValue != -1 && acqValue != *value ) {
27052725 return failure ();
27062726 }
2707- acqValue = op. getLockValue () ;
2727+ acqValue = *value ;
27082728 } else if (op.release ()) {
2709- if (relValue != -1 && relValue != op. getLockValue () ) {
2729+ if (relValue != -1 && relValue != *value ) {
27102730 return failure ();
27112731 }
2712- relValue = op. getLockValue () ;
2732+ relValue = *value ;
27132733 }
27142734 }
27152735 return success ();
@@ -2737,6 +2757,15 @@ LogicalResult UseLockOp::verify() {
27372757 return (*this )->emitOpError (
27382758 " AcquireGreaterEqual is not supported in AIE1." );
27392759
2760+ // Locks used inside a DMA/BD block are configured via static register writes
2761+ // and therefore require a compile-time constant value.
2762+ if (HasSomeParent<MemOp, MemTileDMAOp, ShimDMAOp>::verifyTrait (*this )
2763+ .succeeded () &&
2764+ !getConstantLockValue (*this ))
2765+ return (*this )->emitOpError (
2766+ " lock value in a DMA/BD block must be a compile-time constant "
2767+ " (defined by an arith.constant)." );
2768+
27402769 // Otherwise, AIE.useLock should be inside MemOp, MemTileDMAOp, or
27412770 // ShimDMAOp,
27422771 if (HasSomeParent<MemOp, MemTileDMAOp, ShimDMAOp>::verifyTrait (*this )
@@ -2821,9 +2850,17 @@ static void printTraceRegValue(OpAsmPrinter &printer, Operation *op,
28212850 xilinx::AIE::printTraceEventEnum (printer, value);
28222851}
28232852
2853+ // Helper to parse a LockBlocking enum keyword.
28242854#define GET_OP_CLASSES
28252855#include " aie/Dialect/AIE/IR/AIEOps.cpp.inc"
28262856
2857+ FailureOr<int32_t > UseLockOp::getConstantValue () {
2858+ if (auto value = getConstantLockValue (*this ))
2859+ return *value;
2860+ return emitOpError (" expected the lock value to be a compile-time constant "
2861+ " (defined by an arith.constant)." );
2862+ }
2863+
28272864TileOp SwitchboxOp::getTileOp () {
28282865 return cast<TileElement>(this ->getOperation ()).getTileOp ();
28292866}
0 commit comments