AIE Passes
-aie-assign-bd-ids¶
Assign bd ids to aie.dma_bd ops.
-aie-assign-buffer-addresses¶
Assign memory locations for buffers in each tile
Buffers in a tile generally have an address that does not significantly matter in the design. Hence, most of the time we can instantiate aie.buffer operations without an address. This pass determines updates each aie.buffer operation without an address to have a well-defined address. This enables later passes to have a consistent view of the memory map of a system.
Options¶
-alloc-scheme : Select allocation scheme: basic-sequential or bank-aware. Default is bank-aware, falling back to basic-sequential if it fails.
-aie-assign-core-link-files¶
Infer per-core link_files from func-level link_with attributes
Walks each aie.core and collects the set of external object files it needs by tracing direct func.call edges to func.func declarations that carry a "link_with" string attribute. The result is stored in the CoreOp's "link_files" StrArrayAttr.
Only direct calls (func.call) are resolved. Indirect calls (func.call_indirect) inside a core body emit a warning and are not resolved; add a direct func.call to the required func.func declaration so the pass can trace the dependency.
Core-level "link_with" (deprecated) is also migrated: its value is folded into the set and the attribute is removed from the CoreOp.
func.func declarations that carry "link_with" but are never called from any core emit a warning; their object files will not appear in any core's link_files.
-aie-assign-lock-ids¶
Assigns the lockIDs of locks that do not have IDs.
Assigns the lockIDs of locks that do not have IDs.
-aie-assign-tile-controller-ids¶
Assign controller id per aie.tile_op
For each aie.tile_op used in the design, assign a unique controller ID.
Options¶
-column-wise-unique-ids : Flag to generate controller ids only unique within each column. Otherwise globally unique.
-aie-canonicalize-device¶
Canonicalize Designs to include a toplevel device
This pass inserts a toplevel device operation in designs that do not have one. This allows us to support backwards compatability for older models targetting the VC1902 device without explicit device operations.
-aie-create-pathfinder-flows¶
Route aie.flow and aie.packetflow operations through switchboxes
Uses Pathfinder congestion-aware algorithm. Each aie.flow is replaced with aie.connect operation. Each aie.packetflow is replace with the set of aie.amsel, aie.masterset and aie.packet_rules operations.
Options¶
-route-circuit : Flag to enable aie.flow lowering.
-route-packet : Flag to enable aie.packetflow lowering.
-aie-find-flows¶
Recover flows from switchbox configuration
Under normal circumstances, every configured aie.switchbox operation should contribute to describing an end-to-end flow from one point to another. These flows may be circuit-switched flows (represented by aie.flow) or a packet-switched connection (represensted by aie.packetflow). This pass is primarily used for testing automatic routing.
-aie-generate-column-control-overlay¶
Spawns streaming interconnect network for column control
For each column of AIE tiles being employed in the design, spawn a network of control packet streaming interconnects which overlay on top of the design.
Options¶
-route-shim-to-tct : Flag to generate TCT routing between tile CTRL and shim SOUTH ports. Available options: ['shim-only', 'all-tiles', 'disable'].
-route-shim-to-tile-ctrl : Flag to generate routing between shim dma DMA and tile CTRL ports, for configuration.
-aie-hoist-vector-transfer-pointers¶
Hoist vector transfer pointer computations out of scf.for loops in aie.core regions
This pass optimizes vector transfer operations inside scf.for loops by hoisting pointer computations. It operates on aie.core regions within aie.device operations. When vector transfer operations have indices that depend on the loop induction variable, the pass:
- Flattens multi-dimensional memrefs to 1D
- Computes a base pointer before the loop
- Adds the pointer as a loop iter_arg
- Updates the pointer by a constant stride each iteration
- Replaces the transfer operations to use the iter_arg pointer
This eliminates redundant index computation and affine.apply operations within the loop body, replacing them with simple pointer arithmetic.
This pass must run before scf-to-cf conversion and before cores are outlined to functions, since it operates on scf.for loops within aie.core regions.
-aie-insert-trace-flows¶
Insert packet flows and runtime sequence trace setup
For each aie.trace operation, this pass: - Creates packet flows from trace ports to shim DMA - Groups traces by target shim (minimizes shim usage, ideally 1) - Inserts shim buffer descriptors and DMA control setup per shim tile - Inserts per-tile timer control register writes - Inserts per-shim broadcast and DMA control setup
All trace configuration is injected at the beginning of the runtime sequence, before user data transfer operations.
By default, multiple trace streams are routed to the same shim DMA
channel and drained by a single buffer descriptor. With
distribute-channels, traces are round-robin distributed across two
S2MM DMA channels per shim tile, each with its own BD. Both channels
share the same host buffer argument (arg_idx) and are split by offset:
channel 0 starts at the base offset, channel 1 at base + buffer_size.
The host must allocate 2x buffer_size for the trace buffer.
With lateral-routing, trace destinations are redirected from columns
with active cores to spare shim NOC columns, reducing data path
perturbation. Use lateral-target-col to force a specific target.
Options¶
-shim-channel : S2MM DMA channel to use for trace (default: 1)
-default-bd-id : Buffer descriptor ID for trace (default: 15)
-packet-id-start : Starting packet ID for trace flows (default: 1)
-burst-length : DMA burst length for trace transfers (default: 64 bytes)
-distribute-channels : Distribute traces across multiple S2MM channels per shim tile
-lateral-routing : Route traces to spare columns to minimize data path perturbation
-lateral-target-col : Force lateral routing target column (-1 = auto-detect nearest spare)
-aie-localize-locks¶
Convert global locks to a core-relative index
An individual lock can be referenced by 4 different AIE cores. However, each individual core accesses the lock through a different 'lock address space'. This pass converts a lock in the conceptual global address space into a local index. e.g.:
becomes-aie-lower-cascade-flows¶
Lower aie.cascade_flow operations through aie.configure_cascade operations
Replace each aie.cascade_flow operation with an equivalent set of aie.configure_cascade
operations.
-aie-normalize-address-spaces¶
Remove non-default address spaces
Early in the flow, it is convenient to represent multiple memories using different address spaces. However, after outlining code for AIE engines, the core itself only has access to a single address space. To avoid confusion, this pass normalizes any address spaces remaining in the code, converting them to the default address space.
-aie-objectFifo-stateful-transform¶
Instantiate the buffers and locks of aie.objectFifo.createObjectFifo operations
Replace each aie.objectFifo.createObjectFifo operation with aie.buffer and aie.lock operations in the producer tile. Convert aie.objectFifo.acquire, aie.objectFifo.release and aie.objectFifo.subviewAccess operations into useLock operations by keeping track of acquire/release operations on each objectFifo by each process.
If the producer and consumer tiles of an aie.objectFifo.createObjectFifo operation are not adjacent, the pass also establised aie.flow and aie.dma operations to enable communication between the tiles. Extend the body of each loop that contains operations on objectFifos such that it is unrolled based on the number of elements in the objectFifos. If the number of iterations of the loop cannot be divided pefectly by the unrolling factor, the pass duplicates the loop body after the original loop.
Options¶
-dynamic-objFifos : Use dynamic (loop-preserving) object fifo lowering in cores. When false, use static loop unrolling instead.
-packet-sw-objFifos : Flag to enable aie.packetflow lowering from objectfifos.
-aie-objectfifo-liveness¶
Flag a specific under-buffered coupled-multicast objectFIFO class that hangs at runtime (not a general deadlock detector).
A coupled multicast (broadcast) objectFIFO whose consumers back-pressure the producer forms a dependency cycle. When the producer must re-acquire a slot on a later trip (replay, repeat_count >= 2) while the prior trip's tokens are still outstanding, the round-trip slack (2 * depth) can be smaller than the number of outstanding tokens demanded by the coupled fan-out (array_fan * trip_count). That is a static, structural deadlock: the IR compiles clean and then hangs the array at runtime.
This pass builds the objectFIFO data + back-pressure dependency graph, finds cyclic strongly-connected components (Tarjan), and applies the validated SDF model PER coupled-multicast group (grouped by name base). Each group is scoped independently so an unrelated cycle elsewhere in the device cannot inflate its demand:
demand = array_fan * T (array_fan = the group's multicast fan-out, summed across the SCCs it spans; T = max repeat_count among the fifos in those SCCs) slack = 2 * depth (depth = min depth in the group) DEADLOCK iff T >= 2 AND depth > 0 AND demand > slack
The T >= 2 replay guard avoids false positives on single-trip broadcasts. The analysis is sound for this static SDF class and conservative elsewhere (it never errors outside a proven cyclic under-buffered multicast); it does not claim to catch other deadlock classes.
-aie-place-tiles¶
Place logical tiles onto physical AIE tiles
Sequential placer algorithm places core tiles in a column-major order and places fifo-connected Shim/Mem tiles near its core tiles. One or more aie.logical_tile operation is mapped to one aie.tile.
Options¶
-placer : Placement algorithm to use (default: sequential_placer)
-cores-per-col : Limit number of cores per column (-1 = no limit). Spreads cores across columns for better trace packet routing.
-merge-logical-tiles : When true (default), allow multiple non-core (ShimNOCTile / MemTile) aie.logical_tile ops to share one physical aie.tile if combined DMA channel demand fits. When false, each non-core aie.logical_tile is pinned to its own physical tile. CoreTile placement is unaffected.
-sa-seed : Random seed for SA placer (0 = non-deterministic).
-aie-standard-lowering¶
Lowering operations in AIE cores' regions to Standard
Outline code inside AIE.core operations into the llvm dialect. BufferOp operations are converted to a GlobalMemrefOp and references to those buffers are converted to GetGlobalMemrefOp. Other AIE operations inside the cores are generally lowered to appropriate function intrinsics. Other AIE operations (e.g. CoreOp, TileOp, LockOp) outside the core are removed.
Optionally, tileCol and tileRow can specify a single core to export
Options¶
-device : Device to generate code for
-tilecol : X coordinate of tile to generate code for
-tilerow : Y coordinate of tile to generate code for
-aie-trace-pack-reg-writes¶
Pack multiple register field writes into single register writes
Packs multiple aie.trace.reg operations that write to the same register into a single aie.trace.reg operation with a combined mask and value.
This pass operates in two phases: 1. Convert field+value pairs to mask+shifted_value using register database 2. Merge multiple writes to the same register with non-overlapping masks
Example transformation:
// Before:
aie.trace.reg register="Trace_Event0" field="Trace_Event0" value=33
aie.trace.reg register="Trace_Event0" field="Trace_Event1" value=34
// After:
aie.trace.reg register="Trace_Event0" value=0x22210000 mask=0xFFFF0000
It is an error for two aie.trace.reg in the same aie.trace block to have overlapping masks for the same register.
-aie-trace-to-config¶
Lower high-level trace ops to register configuration ops
Converts aie.trace operations to aie.trace.config operations containing aie.trace.reg operations that specify register field writes.
This pass transforms declarative trace configurations into register-level specifications that can be further lowered to NPU register writes.
Note: This pass only does semantic lowering. NPU write generation happens in aie-inline-trace-config (AIEX dialect).
-aie-vector-to-pointer-loops¶
Transform vector load/store loops to use ptr dialect for explicit pointer arithmetic
This pass transforms scf.for loops containing vector.load/store operations with loop-carried index arguments to use ptr dialect operations.
The transformation makes pointer increment patterns explicit to help the LLVM backend generate efficient post-increment addressing modes (GEP fusion).
Example transformation: Before: scf.for iter_args(%idx = %0) { %v = vector.load %memref[%idx] %next = arith.addi %idx, %stride scf.yield %next }
After: %ptr = ptr.to_ptr %memref %init_ptr = ptr.ptr_add %ptr, %0 scf.for iter_args(%p = %init_ptr) { %m = ptr.from_ptr %p %v = vector.load %m[%c0] %next_p = ptr.ptr_add %p, %stride scf.yield %next_p }
-aie-vector-transfer-lowering¶
Lower vector.transfer_read/write to vector.load/store for AIE
This pass lowers vector.transfer_read operations to vector.load + vector.broadcast
and vector.transfer_write operations to vector.store, when applicable.
It's a wrapper for the upstream populateVectorTransferLoweringPatterns.
TODO: Deprecate this pass once populateVectorTransferLoweringPatterns is included in
convert-to-llvm.