Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
88c0ecb
Add l2 cache control to mte_ub_gm
Jul 8, 2026
b2d513e
Update mte_ub_gm tests for l2 cache control
Jul 8, 2026
e85c839
Tighten mte_ub_gm l2 cache lit checks
Jul 8, 2026
51c5ced
Fix PTODSL mte_ub_gm l2 cache ctl operand
Jul 10, 2026
905e4d6
Update mte_ub_gm textual uses after rebase
Jul 10, 2026
20fafd5
Update TileLang mte_ub_gm l2 cache operand
Jul 13, 2026
3303d50
Support l2cache string policy in DSL mte_ub_gm
Jul 13, 2026
9220c7a
Fix mte_ub_gm l2 cache lit argument checks
Jul 14, 2026
4317f6f
Use l2_cache string surface for DSL mte_ub_gm
Jul 15, 2026
1694bb0
fix(vpto): derive SIMT registers from max threads
KurrinQu Jul 16, 2026
a7d8f3a
Merge pull request #920 from and0d0/489-ub-gm-l2-cache
zhangstevenunity Jul 17, 2026
1d71639
Merge pull request #949 from KurrinQu/fix_simtvf_issues
KurrinQu Jul 17, 2026
beb1095
Remove automatic memory consistency pass
TaoTao-real Jul 17, 2026
4059fa2
Support pre_quant f32_bf16 public mode
Jul 8, 2026
0e2a94a
Lower GM fence with conservative pipe drains
TaoTao-real Jul 17, 2026
b4d96c2
Merge pull request #953 from TaoTao-real/codex/remove-memory-consiste…
zhangstevenunity Jul 17, 2026
3d82b47
refactor(ptodsl): Remove max_regs parameter from @pto.simt decorator
kuri780 Jul 17, 2026
79463ac
Merge pull request #955 from kuri780/feature/remove-simt-max-regs-api
Zhendong404 Jul 17, 2026
349b603
Merge pull request #922 from and0d0/489-pre_quant-public-mode
Zhendong404 Jul 18, 2026
3589c59
fix(TileOps): correct tload/tstore strides to physical src stride (#924)
TelGome Jul 18, 2026
aab41d7
feat(ptodsl): expand A5 intra sync surface
Jul 20, 2026
f75bed7
fix(sync): validate A5 intra event id range
Jul 20, 2026
9d426e7
docs(sync): document A5 physical intra event ids
Jul 20, 2026
90ec7fe
fix(sync): stop mirroring A5 EmitC sync set ids
andodo Jul 22, 2026
cec062e
fix(sync): remove stale EmitC pipe variable
andodo Jul 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
416 changes: 40 additions & 376 deletions docs/designs/ptoas-memory-consistency-design.md

Large diffs are not rendered by default.

24 changes: 12 additions & 12 deletions docs/designs/ptodsl-simt-micro-op-api-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ math, conversion, sync, and state preservation.
Current PTO-DSL already has a narrow SIMT surface:

- `@pto.simt` decorator and `with pto.simt():` inline scope.
- `@pto.simt(max_threads=..., max_regs=...)` optional entry resource
- `@pto.simt(max_threads=...)` optional entry resource
attributes.
- `pto.store_vfsimt_info(dim_z, dim_y, dim_x)`.
- `pto.get_tid_x()`, `pto.get_tid_y()`, `pto.get_tid_z()`.
Expand Down Expand Up @@ -284,15 +284,14 @@ explicit peer function symbol.

### 5.6 `@pto.simt` Decorator Attributes

SIMT entry functions may carry optional VPTO attributes:
SIMT entry functions may carry an optional VPTO attribute:

- `pto.simt_max_threads`
- `pto.simt_max_regs`

PTO-DSL exposes them through `@pto.simt`:
PTO-DSL exposes it through `@pto.simt`:

```python
@pto.simt(max_threads=256, max_regs=48)
@pto.simt(max_threads=256)
def body(...):
...
```
Expand All @@ -302,14 +301,13 @@ Lowering:
```mlir
func.func @body(...) attributes {
pto.simt_entry,
pto.simt_max_threads = 256 : i32,
pto.simt_max_regs = 48 : i32
pto.simt_max_threads = 256 : i32
}
```

Lowering attaches these attributes to the generated specialized helper function,
not to the authored Python symbol. Omitting either argument emits no explicit
attribute and lets backend defaults apply.
Lowering attaches the attribute to the generated specialized helper function,
not to the authored Python symbol. Omitting the argument emits no explicit
attribute and lets the backend default (1024) apply.

Validation:

Expand Down Expand Up @@ -432,8 +430,10 @@ Minimum Python/frontend tests:
produces distinct helper functions and distinct traced bodies.
8. `pto.simt_launch` callee attributes reference the actual generated helper
symbols.
9. `@pto.simt(max_threads=..., max_regs=...)` emits `pto.simt_max_threads` and
`pto.simt_max_regs` on the generated helper function.
9. `@pto.simt(max_threads=...)` emits `pto.simt_max_threads` on the generated
helper function. The register budget (`simt-max-registers`) is automatically
derived from `max_threads` by the backend according to the hardware resource
partition and is no longer a configurable attribute.

Suggested lit/frontend assertions:

Expand Down
12 changes: 6 additions & 6 deletions docs/isa/micro-isa/01-pipeline-sync.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ pipe_barrier(pipe);

```mlir
// Both stores target the same GM address — order matters!
pto.mte_ub_gm %ub_partial_0, %gm_result, ...
pto.mte_ub_gm %ub_partial_0, %gm_result, %len_burst ...
// Without pipe_barrier, MTE3 could execute the second copy before the first
// completes, producing a non-deterministic result at %gm_result.
pto.pipe_barrier "PIPE_MTE3"
// After barrier: first copy is guaranteed complete. Second copy overwrites deterministically.
pto.mte_ub_gm %ub_partial_1, %gm_result, ...
pto.mte_ub_gm %ub_partial_1, %gm_result, %len_burst ...
```

---
Expand Down Expand Up @@ -367,7 +367,7 @@ pto.set_flag["PIPE_V", "PIPE_MTE3", "EVENT_ID0"]
// MTE3 waits until Vector's signal arrives
pto.wait_flag["PIPE_V", "PIPE_MTE3", "EVENT_ID0"]

pto.mte_ub_gm %ub_out, %gm_out, ...
pto.mte_ub_gm %ub_out, %gm_out, %len_burst ...
```

**Key property:** Every cross-pipeline edge is an explicit `(set_flag, wait_flag)` pair. Simple for straight-line code, but gets verbose in loops (see Example 3).
Expand Down Expand Up @@ -407,7 +407,7 @@ pto.rls_buf "PIPE_V", %bufid_ub_out, %c0 : i64, i64
// ─── Stage 3: MTE3 stores result to GM ───
// MTE3 acquires ub_out — blocks until Vector releases it (RAW: V write → MTE3 read)
pto.get_buf "PIPE_MTE3", %bufid_ub_out, %c0 : i64, i64
pto.mte_ub_gm %ub_out, %gm_out, ...
pto.mte_ub_gm %ub_out, %gm_out, %len_burst ...
// MTE3 done reading ub_out — release so Vector can reuse it in next iteration
pto.rls_buf "PIPE_MTE3", %bufid_ub_out, %c0 : i64, i64
```
Expand Down Expand Up @@ -483,7 +483,7 @@ scf.for %i = %c0 to %N step %c1 {
// ── MTE3: store result from buf_out[i%2] to GM ──
// RAW: wait for Vector to finish writing buf_out[i%2]
pto.wait_flag["PIPE_V", "PIPE_MTE3", "EVT_OUT_FWD_{pp}"]
pto.mte_ub_gm %ub_out[%pp], %gm_out[%i], ...
pto.mte_ub_gm %ub_out[%pp], %gm_out[%i], %len_burst ...
// WAR: tell Vector "done reading buf_out[i%2]"
pto.set_flag["PIPE_MTE3", "PIPE_V", "EVT_OUT_REV_{pp}"]
}
Expand Down Expand Up @@ -534,7 +534,7 @@ scf.for %i = %c0 to %N step %c1 {
// ── MTE3: store result ──
// Acquires out[i%2] — blocks until Vector releases it (RAW: automatic)
pto.get_buf "PIPE_MTE3", %bufid_out[%pp], %c0 : i64, i64
pto.mte_ub_gm %ub_out[%pp], %gm_out[%i], ...
pto.mte_ub_gm %ub_out[%pp], %gm_out[%i], %len_burst ...
pto.rls_buf "PIPE_MTE3", %bufid_out[%pp], %c0 : i64, i64
}
// No post-loop drain needed — last rls_buf completes the pipeline.
Expand Down
19 changes: 11 additions & 8 deletions docs/isa/micro-isa/02-dma-copy.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,13 @@ pto.mte_gm_ub %gm_in, %ub_out, %cache, %len_burst
- **syntax:**
```mlir
pto.mte_ub_gm %ub_src, %gm_dst, %len_burst
nburst(%n_burst, %src_stride, %dst_stride)
nburst(%n_burst, %src_stride, %dst_stride) l2_cache_ctl(%l2_cache_ctl)
[loop(%loop_count, %loop_src_stride, %loop_dst_stride)]*
: !pto.ptr<T, ub>, !pto.ptr<T, gm>, i64, i64, i64, i64,
: !pto.ptr<T, ub>, !pto.ptr<T, gm>, i64, i64, i64, i64, i64,
[loop i64, i64, i64,]*
```
- **semantics:** Grouped UB→GM DMA transfer. `nburst(...)` defines the innermost repeated burst transfer, and optional `loop(...)` groups add outer repetition levels.
The `l2_cache_ctl(...)` group is optional in textual VPTO IR; when omitted, lowering uses `0`.

**Parameter Table:**

Expand All @@ -88,6 +89,7 @@ pto.mte_ub_gm %ub_src, %gm_dst, %len_burst
| `%gm_dst` | ptr | GM destination pointer (`!pto.ptr<T, gm>`) |
| `%len_burst` | 16 bits | Contiguous bytes transferred per burst row |
| `nburst(%n_burst, %src_stride, %dst_stride)` | 16 bits / 21 bits / 40 bits | Required innermost burst group: count, UB source stride, GM destination stride |
| `l2_cache_ctl(%l2_cache_ctl)` | 4 bits | Optional GM store-side L2 cache control; omitted means `0` |
| `loop(%loop_count, %loop_src_stride, %loop_dst_stride)` | 21 bits / 21 bits / 40 bits | Optional outer repetition group: count, UB source stride, GM destination stride |

**Constraints:**
Expand All @@ -103,10 +105,10 @@ pto.mte_ub_gm %ub_src, %gm_dst, %len_burst

```mlir
pto.mte_ub_gm %ub_in, %gm_out, %len_burst
nburst(%rows, %ub_row_stride, %gm_row_stride)
nburst(%rows, %ub_row_stride, %gm_row_stride) l2_cache_ctl(%l2_cache_ctl)
loop(%tiles, %ub_tile_stride, %gm_tile_stride)
loop(%batches, %ub_batch_stride, %gm_batch_stride)
: !pto.ptr<f16, ub>, !pto.ptr<f16, gm>, i64, i64, i64, i64,
: !pto.ptr<f16, ub>, !pto.ptr<f16, gm>, i64, i64, i64, i64, i64,
loop i64, i64, i64, loop i64, i64, i64
```

Expand Down Expand Up @@ -336,6 +338,7 @@ For a form
```mlir
pto.mte_ub_gm %ub_src, %dst, %len_burst
nburst(%n_burst, %src_stride, %dst_stride)
l2_cache_ctl(%l2_cache_ctl)
loop(%c0, %s0, %d0)
loop(%c1, %s1, %d1)
...
Expand Down Expand Up @@ -507,8 +510,8 @@ GM (dest, 32 × 32 f32):

```mlir
pto.mte_ub_gm %ub_out, %arg1, %c128_i64
nburst(%c32_i64, %c128_i64, %c128_i64)
: !pto.ptr<f32, ub>, !pto.ptr<f32, gm>, i64, i64, i64, i64
nburst(%c32_i64, %c128_i64, %c128_i64) l2_cache_ctl(%c0_i64)
: !pto.ptr<f32, ub>, !pto.ptr<f32, gm>, i64, i64, i64, i64, i64
```

---
Expand Down Expand Up @@ -545,8 +548,8 @@ GM (dest, into 1024 × 512 matrix):

```mlir
pto.mte_ub_gm %ub_ptr, %gm_ptr, %c256_i64
nburst(%c64_i64, %c256_i64, %c1024_i64)
: !pto.ptr<f16, ub>, !pto.ptr<f16, gm>, i64, i64, i64, i64
nburst(%c64_i64, %c256_i64, %c1024_i64) l2_cache_ctl(%c0_i64)
: !pto.ptr<f16, ub>, !pto.ptr<f16, gm>, i64, i64, i64, i64, i64
```

---
Expand Down
32 changes: 20 additions & 12 deletions docs/isa/micro-isa/17-simt.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,24 +48,32 @@ The current PTO SIMT surface supports these operation families:
| Conversion | `pto.convert` |
| Entry synchronization and state | `pto.syncthreads`, `pto.threadfence`, `pto.threadfence_block`, `pto.keep`, `pto.resume` |

Two optional function attributes may be attached to a `pto.simt_entry`
One optional function attribute may be attached to a `pto.simt_entry`
function:

| Function attribute | Type | Default | Meaning |
|--------------------|------|---------|---------|
| `pto.simt_max_threads` | signless `i32` integer attribute | `1024` | Compile-time launch envelope. It should cover the largest `dim_x * dim_y * dim_z` launch count used for this entry. |
| `pto.simt_max_regs` | signless `i32` integer attribute | `32` | Compile-time scalar register budget per workitem. Lower values constrain scalar live state; higher values permit more scalar live values with higher resource pressure. |

Both attributes are optional. If present, they must be positive `i32`
attributes and may only appear on functions that also carry `pto.simt_entry`.
They do not launch work by themselves; the actual workitem count comes from
`pto.store_vfsimt_info` or `pto.simt_launch`.
`pto.simt_max_threads` may only appear on functions that also carry
`pto.simt_entry`. It must be a positive `i32` value no greater than 2048. The
thread envelope determines the emitted scalar register budget:

| `pto.simt_max_threads` | Emitted `simt-max-registers` |
|------------------------|------------------------------|
| `1` to `256` | `128` |
| `257` to `512` | `64` |
| `513` to `1024` | `32` |
| `1025` to `2048` | `16` |

The register budget is derived automatically and is not independently
configurable. `pto.simt_max_threads` does not launch work by itself; the actual
workitem count comes from `pto.store_vfsimt_info` or `pto.simt_launch`.

```mlir
func.func @body(%dst: !pto.ptr<i32, ub>)
attributes {pto.simt_entry,
pto.simt_max_threads = 256 : i32,
pto.simt_max_regs = 48 : i32} {
pto.simt_max_threads = 256 : i32} {
return
}
```
Expand Down Expand Up @@ -1071,8 +1079,8 @@ func.call @body(%ub_out) : (!pto.ptr<i32, ub>) -> ()
pto.set_flag["PIPE_V", "PIPE_MTE3", "EVENT_ID0"]
pto.wait_flag["PIPE_V", "PIPE_MTE3", "EVENT_ID0"]
pto.mte_ub_gm %ub_out, %gm_out, %len
nburst(%n, %src_stride, %dst_stride)
: !pto.ptr<i32, ub>, !pto.ptr<i32, gm>, i64, i64, i64, i64
nburst(%n, %src_stride, %dst_stride) l2_cache_ctl(%l2_cache_ctl)
: !pto.ptr<i32, ub>, !pto.ptr<i32, gm>, i64, i64, i64, i64, i64
```

For pipeline synchronization semantics, see
Expand Down Expand Up @@ -1103,8 +1111,8 @@ module attributes {pto.target_arch = "a5",
pto.set_flag["PIPE_V", "PIPE_MTE3", "EVENT_ID0"]
pto.wait_flag["PIPE_V", "PIPE_MTE3", "EVENT_ID0"]
pto.mte_ub_gm %ub_out, %out, %c128_i64
nburst(%c32_i64, %c128_i64, %c128_i64)
: !pto.ptr<i32, ub>, !pto.ptr<i32, gm>, i64, i64, i64, i64
nburst(%c32_i64, %c128_i64, %c128_i64) l2_cache_ctl(%c0_i64)
: !pto.ptr<i32, ub>, !pto.ptr<i32, gm>, i64, i64, i64, i64, i64
pto.barrier #pto.pipe<PIPE_ALL>
return
}
Expand Down
9 changes: 7 additions & 2 deletions docs/vpto-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -379,8 +379,8 @@ pto.vecscope {
pto.set_flag["PIPE_V", "PIPE_MTE3", "EVENT_ID0"]
pto.wait_flag["PIPE_V", "PIPE_MTE3", "EVENT_ID0"]
pto.mte_ub_gm %8, %14, %c128_i64
nburst(%c32_i64, %c128_i64, %c128_i64)
: !pto.ptr<f32, ub>, !pto.ptr<f32, gm>, i64, i64, i64, i64
nburst(%c32_i64, %c128_i64, %c128_i64) l2_cache_ctl(%c0_i64)
: !pto.ptr<f32, ub>, !pto.ptr<f32, gm>, i64, i64, i64, i64, i64
```

### Example: Strict VecScope
Expand Down Expand Up @@ -479,6 +479,11 @@ pipeline** commits the signal, ensuring the preceding operation on that pipeline
before the signal is issued. The receiver specifies which **local pipeline** should stall until
the signal arrives. This is the fundamental IPC primitive for Cube–Vector cooperation on A5.

For the public `pto.sync.set` / `pto.sync.wait` surface on A5, event IDs are physical semaphore
IDs in the `0-31` range. AIV subblock 0 uses event IDs `0-15`, and AIV subblock 1 uses event
IDs `16-31`. Code that signals or waits for both AIV subblocks should explicitly emit both
the base ID and `base_id + 16`.

> **Note:** `pto.set_cross_core` / `pto.wait_cross_core` operate at **multi-cluster** scope and
> are not used for intra-cluster communication.

Expand Down
21 changes: 10 additions & 11 deletions include/PTO/IR/PTOOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -2962,16 +2962,13 @@ def CmoCacheInvalidOp : PTO_Op<"cmo.cacheinvalid"> {
`dcci((__gm__ void*)0, cache_line_t::ENTIRE_DATA_CACHE)`.

The single-cache-line form carries the GM payload address selected by the
producer DSL/user. When it is required for a cacheable scalar path, it
lowers to `dcci(addr, cache_line_t::SINGLE_CACHE_LINE)`. When it only marks
a non-cacheable payload for signal release analysis, MemoryConsistency may
consume it as marker-only IR and erase it before EmitC lowering.
producer DSL/user and lowers to
`dcci(addr, cache_line_t::SINGLE_CACHE_LINE)`.

MemoryConsistency interprets both forms as explicit CMO boundaries on
producer release and consumer acquire paths. It also uses the addressed form
to match a TNotify payload against pending MTE2, MTE3, FIX, or scalar GM
accesses before deciding which pipe drains are required. Precise coverage of
the selected line is the producer DSL/user's responsibility in this phase.
This op is an explicit CMO boundary. PTOAS no longer runs the historical
MemoryConsistency analysis pass that consumed marker-only CMO ops or inferred
signal/payload pipe drains, so precise placement and coverage are the
producer DSL/user's responsibility.
}];

let arguments = (ins
Expand All @@ -2988,8 +2985,10 @@ def FenceBarrierAllOp : PTO_Op<"fence.barrier_all"> {
let description = [{
Memory fence for a visibility scope. Around signal/payload communication it
can be used as the producer-side publish barrier or the consumer-side
acquire barrier depending on placement. `scope = gm` lowers to
`dsb(DSB_DDR)`.
acquire barrier depending on placement. In EmitC, `scope = gm` and
`scope = all` conservatively drain MTE2, MTE3, and FIX before lowering to
`dsb(DSB_DDR)`, so users do not need to separately model those producer
pipe classes before a GM visibility fence.
}];

let arguments = (ins PTO_FenceScopeAttr:$scope);
Expand Down
9 changes: 6 additions & 3 deletions include/PTO/IR/VPTOOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -2645,7 +2645,7 @@ def PTO_CopyUbufToGmOp : PTO_Op<"copy_ubuf_to_gm", [
I64:$sid,
I64:$n_burst,
I64:$len_burst,
I64:$reserved,
I64:$l2_cache_ctl,
I64:$burst_dst_stride,
I64:$burst_src_stride
);
Expand All @@ -2656,9 +2656,9 @@ def PTO_CopyUbufToGmOp : PTO_Op<"copy_ubuf_to_gm", [

let assemblyFormat = [{
$source `,` $destination `,` $sid `,` $n_burst `,` $len_burst `,`
$reserved `,` $burst_dst_stride `,` $burst_src_stride
$l2_cache_ctl `,` $burst_dst_stride `,` $burst_src_stride
attr-dict `:` type($source) `,` type($destination) `,` type($sid) `,` type($n_burst) `,`
type($len_burst) `,` type($reserved) `,`
type($len_burst) `,` type($l2_cache_ctl) `,`
type($burst_dst_stride) `,` type($burst_src_stride)
}];
}
Expand All @@ -2674,6 +2674,7 @@ def PTO_MteUbGmOp : PTO_Op<"mte_ub_gm", [
I64:$n_burst,
I64:$nburst_src_stride,
I64:$nburst_dst_stride,
Optional<I64>:$l2_cache_ctl,
Variadic<I64>:$loop_counts,
Variadic<I64>:$loop_src_strides,
Variadic<I64>:$loop_dst_strides
Expand All @@ -2690,13 +2691,15 @@ def PTO_MteUbGmOp : PTO_Op<"mte_ub_gm", [
"::mlir::Value":$destination,
"::mlir::Value":$lenBurst,
"::mlir::pto::DmaLoopConfig":$nburst,
"::mlir::Value":$l2CacheCtl,
"::llvm::ArrayRef<::mlir::pto::DmaLoopConfig>":$loops
)>,
OpBuilder<(ins
"::mlir::Value":$source,
"::mlir::Value":$destination,
"::mlir::Value":$lenBurst,
"::mlir::pto::DmaLoopConfig":$nburst,
"::mlir::Value":$l2CacheCtl,
"::std::optional<::mlir::pto::DmaLoopConfig>":$loop1,
"::std::optional<::mlir::pto::DmaLoopConfig>":$loop2
)>
Expand Down
1 change: 0 additions & 1 deletion include/PTO/Transforms/Passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ std::unique_ptr<Pass> createPTOValidateIntToPtrUsesPass();
std::unique_ptr<Pass> createPTORematerializeFixpipeVectorQuantPass();
std::unique_ptr<Pass> createPTOMaterializeTileHandlesPass();
std::unique_ptr<Pass> createPTOResolveBufferSelectPass();
std::unique_ptr<Pass> createPTOMemoryConsistencyPass();
std::unique_ptr<Pass> createInferPTOLayoutPass();
std::unique_ptr<Pass> createPTOA5NormalizeTMovPass();
std::unique_ptr<Pass> createPTORemoveIdentityTMovPass();
Expand Down
19 changes: 0 additions & 19 deletions include/PTO/Transforms/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -782,25 +782,6 @@ def PTOResolveBufferSelect : Pass<"pto-resolve-buffer-select", "ModuleOp"> {
];
}

def PTOMemoryConsistency : Pass<"pto-memory-consistency", "ModuleOp"> {
let summary = "Annotate PTO memory consistency actions before backend lowering";
let description = [{
Analyzes signal/payload ordering requirements and annotates communication
signal ops and scalar GM consumers with release/acquire actions consumed by
backend lowering. It covers TNotify release actions for direct MTE
operations, macro-op MTE3 phases, cacheable scalar GM stores, and
conservative TWait/TTest acquire invalidation for scalar GM loads.
}];

let constructor = "mlir::pto::createPTOMemoryConsistencyPass()";

let dependentDialects = [
"mlir::pto::PTODialect",
"mlir::func::FuncDialect",
"mlir::scf::SCFDialect"
];
}

def PTOUnrollSIMTFor : Pass<"pto-unroll-simt-for", "func::FuncOp"> {
let summary =
"Unroll explicitly annotated scf.for loops in pto.simt_entry functions";
Expand Down
Loading
Loading