# MLIR Passes 全解(中英对照) > **源文档**:MLIR — *Passes*(),即本目录下的 `Passes - MLIR.pdf`(142 页,网页另存为 PDF)。 > **说明**:本文件为中英对照翻译。每个 pass 先给英文原文(**EN:**),再给中文译文(**中文:**);所有 MLIR 代码示例**原样保留、未做翻译**。术语尽量保留英文并在括号内给出中文解释。 > **规模**:共 34 个分类,316 个 pass。翻译由源 PDF 提取文本后按文档顺序逐条完成。 ## 目录(Table of Contents) - **General Transformation Passes** — 22 个 pass - `-bubble-down-memory-space-casts` - `-canonicalize` - `-composite-fixed-point-pass` - `-control-flow-sink` - `-cse` - `-generate-runtime-verification` - `-inline` - `-loop-invariant-code-motion` - `-loop-invariant-subset-hoisting` - `-mem2reg` - `-print-ir` - `-print-op-stats` - `-remove-dead-values` - `-sccp` - `-snapshot-op-locations` - `-sroa` - `-strip-debuginfo` - `-symbol-dce` - `-symbol-privatize` - `-topological-sort` - `-trivial-dce` - `-view-op-graph` - **Bufferization Passes** — 13 个 pass - `-buffer-deallocation-simplification` - `-buffer-hoisting` - `-buffer-loop-hoisting` - `-buffer-results-to-out-params` - `-bufferization-lower-deallocations` - `-drop-equivalent-buffer-results` - `-eliminate-empty-tensors` - `-empty-tensor-to-alloc-tensor` - `-one-shot-bufferize` - `-optimize-allocation-liveness` - `-ownership-based-buffer-deallocation` - `-promote-buffers-to-stack` - `-static-memory-planner-analysis` - **Conversion Passes** — 89 个 pass - `-acc-to-llvm` - `-arm-neon-2d-to-intr` - `-convert-affine-for-to-gpu` - `-convert-amdgpu-to-rocdl` - `-convert-arith-to-amdgpu` - `-convert-arith-to-apfloat` - `-convert-arith-to-arm-sme` - `-convert-arith-to-emitc` - `-convert-arith-to-llvm` - `-convert-arith-to-spirv` - `-convert-arm-sme-to-llvm` - `-convert-arm-sme-to-scf` - `-convert-async-to-llvm` - `-convert-bufferization-to-memref` - `-convert-cf-to-llvm` - `-convert-cf-to-spirv` - `-convert-complex-to-libm` - `-convert-complex-to-llvm` - `-convert-complex-to-rocdl-library-calls` - `-convert-complex-to-spirv` - `-convert-complex-to-standard` - `-convert-func-to-emitc` - `-convert-func-to-llvm` - `-convert-func-to-spirv` - `-convert-gpu-to-llvm-spv` - `-convert-gpu-to-nvvm` - `-convert-gpu-to-rocdl` - `-convert-gpu-to-spirv` - `-convert-index-to-llvm` - `-convert-index-to-spirv` - `-convert-linalg-to-std` - `-convert-math-to-apfloat` - `-convert-math-to-emitc` - `-convert-math-to-funcs` - `-convert-math-to-libm` - `-convert-math-to-llvm` - `-convert-math-to-nvvm` - `-convert-math-to-rocdl` - `-convert-math-to-spirv` - `-convert-math-to-xevm` - `-convert-memref-to-emitc` - `-convert-memref-to-spirv` - `-convert-nvgpu-to-nvvm` - `-convert-nvvm-to-llvm` - `-convert-openacc-to-scf` - `-convert-openmp-to-llvm` - `-convert-parallel-loops-to-gpu` - `-convert-pdl-to-pdl-interp` - `-convert-scf-to-cf` - `-convert-scf-to-emitc` - `-convert-scf-to-openmp` - `-convert-scf-to-spirv` - `-convert-shape-constraints` - `-convert-shape-to-std` - `-convert-shard-to-mpi` - `-convert-spirv-to-llvm` - `-convert-tensor-to-linalg` - `-convert-tensor-to-spirv` - `-convert-to-emitc` - `-convert-to-llvm` - `-convert-ub-to-llvm` - `-convert-ub-to-spirv` - `-convert-vector-to-amx` - `-convert-vector-to-arm-sme` - `-convert-vector-to-gpu` - `-convert-vector-to-llvm` - `-convert-vector-to-scf` - `-convert-vector-to-spirv` - `-convert-vector-to-xegpu` - `-convert-xegpu-to-xevm` - `-convert-xevm-to-llvm` - `-finalize-memref-to-llvm` - `-gpu-to-llvm` - `-lift-cf-to-scf` - `-lower-affine` - `-lower-host-to-llvm` - `-map-memref-spirv-storage-class` - `-raise-scf-to-affine` - `-raise-wasm-mlir` - `-reconcile-unrealized-casts` - `-set-llvm-module-datalayout` - `-tosa-to-arith` - `-tosa-to-linalg` - `-tosa-to-linalg-named` - `-tosa-to-mlprogram` - `-tosa-to-scf` - `-tosa-to-spirv-tosa` - `-tosa-to-spirv-tosa-mark-graph-constants` - `-tosa-to-tensor` - **‘acc’ Dialect Passes** — 21 个 pass - `-acc-bind-routine` - `-acc-cg-to-gpu` - `-acc-compute-lowering` - `-acc-declare-gpu-module-insertion` - `-acc-emit-remarks-data` - `-acc-emit-remarks-loop` - `-acc-emit-remarks-private` - `-acc-if-clause-lowering` - `-acc-implicit-data` - `-acc-implicit-declare` - `-acc-implicit-routine` - `-acc-legalize-serial` - `-acc-loop-tiling` - `-acc-recipe-materialization` - `-acc-routine-lowering` - `-acc-routine-to-gpu-func` - `-acc-specialize-for-device` - `-acc-specialize-for-host` - `-offload-livein-value-canonicalization` - `-offload-target-verifier` - `-openacc-legalize-data-values` - **‘affine’ Dialect Passes** — 19 个 pass - `-affine-data-copy-generate` - `-affine-expand-index-ops` - `-affine-expand-index-ops-as-affine` - `-affine-fold-memref-alias-ops` - `-affine-loop-coalescing` - `-affine-loop-fusion` - `-affine-loop-invariant-code-motion` - `-affine-loop-normalize` - `-affine-loop-tile` - `-affine-loop-unroll` - `-affine-loop-unroll-jam` - `-affine-parallelize` - `-affine-pipeline-data-transfer` - `-affine-raise-from-memref` - `-affine-scalrep` - `-affine-simplify-min-max` - `-affine-simplify-structures` - `-affine-simplify-with-bounds` - `-affine-super-vectorize` - **‘amdgpu’ Dialect Passes** — 3 个 pass - `-amdgpu-emulate-atomics` - `-amdgpu-maskedload-to-load` - `-amdgpu-resolve-strided-metadata` - **‘arith’ Dialect Passes** — 6 个 pass - `-arith-emulate-unsupported-floats` - `-arith-emulate-wide-int` - `-arith-expand` - `-arith-int-range-narrowing` - `-arith-unsigned-when-equivalent` - `-int-range-optimizations` - **‘arm_sme’ Dialect Passes** — 4 个 pass - `-arm-sme-outer-product-fusion` - `-arm-sme-vector-legalization` - `-enable-arm-streaming` - `-test-arm-sme-tile-allocation` - **‘arm_sve’ Dialect Passes** — 1 个 pass - `-arm-sve-legalize-vector-storage` - **‘async’ Dialect Passes** — 6 个 pass - `-async-func-to-async-runtime` - `-async-parallel-for` - `-async-runtime-policy-based-ref-counting` - `-async-runtime-ref-counting` - `-async-runtime-ref-counting-opt` - `-async-to-async-runtime` - **’emitc’ Dialect Passes** — 3 个 pass - `-form-expressions` - `-mlgo-add-reflection-map` - `-wrap-emitc-func-in-class` - **‘func’ Dialect Passes** — 1 个 pass - `-duplicate-function-elimination` - **‘gpu’ Dialect Passes** — 11 个 pass - `-gpu-async-region` - `-gpu-decompose-memrefs` - `-gpu-eliminate-barriers` - `-gpu-kernel-outlining` - `-gpu-launch-sink-index-computations` - `-gpu-map-parallel-loops` - `-gpu-module-to-binary` - `-nvvm-attach-target` - `-rocdl-attach-target` - `-spirv-attach-target` - `-xevm-attach-target` - **’linalg’ Dialect Passes** — 13 个 pass - `-convert-elementwise-to-linalg` - `-convert-linalg-to-affine-loops` - `-convert-linalg-to-loops` - `-convert-linalg-to-parallel-loops` - `-linalg-block-pack-matmul` - `-linalg-fold-into-elementwise` - `-linalg-fold-unit-extent-dims` - `-linalg-fuse-elementwise-ops` - `-linalg-generalize-named-ops` - `-linalg-inline-scalar-operands` - `-linalg-morph-ops` - `-linalg-specialize-generic-ops` - `-simplify-depthwise-conv` - **’llvm’ Dialect Passes** — 5 个 pass - `-ensure-debug-info-scope-on-llvm-func` - `-llvm-add-comdats` - `-llvm-legalize-for-export` - `-llvm-request-c-wrappers` - `-llvm-use-default-visibility` - **’llvm’ Target Passes** — 2 个 pass - `-llvm-target-to-data-layout` - `-llvm-target-to-target-features` - **‘math’ Dialect Passes** — 4 个 pass - `-math-expand-ops` - `-math-extend-to-supported-types` - `-math-sincos-fusion` - `-math-uplift-to-fma` - **‘memref’ Dialect Passes** — 11 个 pass - `-expand-realloc` - `-expand-strided-metadata` - `-flatten-memref` - `-fold-memref-alias-ops` - `-memref-elide-reinterpret-cast` - `-memref-emulate-wide-int` - `-memref-expand` - `-normalize-memrefs` - `-reify-result-shapes` - `-resolve-ranked-shaped-type-result-dims` - `-resolve-shaped-type-result-dims` - **‘omp’ Dialect Passes** — 4 个 pass - `-omp-host-op-filter` - `-omp-mark-declare-target` - `-omp-offload-privatization-prepare` - `-omp-stack-to-shared` - **‘shard’ Dialect Passes** — 3 个 pass - `-shard-partition` - `-shard-simplify` - `-sharding-propagation` - **‘ml_program’ Dialect Passes** — 1 个 pass - `-mlprogram-pipeline-globals` - **’nvgpu’ Dialect Passes** — 1 个 pass - `-nvgpu-optimize-shared-memory` - **’nvvm’ Dialect Passes** — 1 个 pass - `-llvm-optimize-for-nvvm-target` - **‘quant’ Dialect Passes** — 3 个 pass - `-lower-quant-ops` - `-normalize-quant-types` - `-strip-func-quant-types` - **Reducer Passes** — 2 个 pass - `-opt-reduction-pass` - `-reduction-tree` - **‘scf’ Dialect Passes** — 12 个 pass - `-scf-for-loop-canonicalization` - `-scf-for-loop-peeling` - `-scf-for-loop-range-folding` - `-scf-for-loop-specialization` - `-scf-for-to-while` - `-scf-forall-to-for` - `-scf-forall-to-parallel` - `-scf-parallel-for-to-nested-fors` - `-scf-parallel-loop-fusion` - `-scf-parallel-loop-specialization` - `-scf-parallel-loop-tiling` - `-test-scf-parallel-loop-collapsing` - **‘shape’ Dialect Passes** — 3 个 pass - `-outline-shape-computation` - `-remove-shape-constraints` - `-shape-to-shape-lowering` - **‘sparse_tensor’ Dialect Passes** — 16 个 pass - `-lower-sparse-foreach-to-scf` - `-lower-sparse-iteration-to-scf` - `-lower-sparse-ops-to-foreach` - `-pre-sparsification-rewrite` - `-sparse-assembler` - `-sparse-buffer-rewrite` - `-sparse-gpu-codegen` - `-sparse-reinterpret-map` - `-sparse-space-collapse` - `-sparse-storage-specifier-to-llvm` - `-sparse-tensor-codegen` - `-sparse-tensor-conversion` - `-sparse-vectorization` - `-sparsification` - `-sparsification-and-bufferization` - `-stage-sparse-ops` - **‘spv’ Dialect Passes** — 8 个 pass - `-decorate-spirv-composite-type-layout` - `-spirv-canonicalize-gl` - `-spirv-lower-abi-attrs` - `-spirv-promote-to-replicated-constants` - `-spirv-rewrite-inserts` - `-spirv-unify-aliased-resource` - `-spirv-update-vce` - `-spirv-webgpu-prepare` - **’tensor’ Dialect Passes** — 2 个 pass - `-fold-tensor-subset-ops` - `-scalarize-single-element-tensor-return` - **’transform’ Dialect Passes** — 4 个 pass - `-transform-dialect-check-uses` - `-transform-infer-effects` - `-transform-interpreter` - `-transform-preload-library` - **‘vector’ Dialect Passes** — 3 个 pass - `-lower-vector-mask` - `-lower-vector-multi-reduction` - `-lower-vector-to-from-elements-to-shuffle-tree` - **TOSA Dialect Passes** — 13 个 pass - `-tosa-arith-const-to-tosa-const` - `-tosa-attach-target` - `-tosa-convert-integer-type-to-signless` - `-tosa-downgrade-1-1-to-1-0` - `-tosa-experimental-input-shape` - `-tosa-infer-shapes` - `-tosa-layerwise-constant-fold` - `-tosa-make-broadcastable` - `-tosa-narrow-f64-to-f32` - `-tosa-narrow-i64-to-i32` - `-tosa-optional-decompositions` - `-tosa-reduce-transposes` - `-tosa-validate` - **XeGPU Dialect Passes** — 6 个 pass - `-xegpu-blocking` - `-xegpu-optimize-peephole` - `-xegpu-propagate-layout` - `-xegpu-sg-to-lane-distribute` - `-xegpu-vector-linearize` - `-xegpu-wg-to-sg-distribute` ## General Transformation Passes(通用变换 Pass) ### -bubble-down-memory-space-casts **EN:** Bubbles down memory-space cast operations. This pass tries to iteratively bubble down all possible memory-space cast operations. It is important to note that the determination of which casts are bubbled down is based on the interfaces MemorySpaceCastConsumerOpInterface, and MemorySpaceCastOpInterface, and not the pass. The pass only looks for operations implementing the MemorySpaceCastConsumerOpInterface interface, and invoking the interface methods to perform the bubbling down. **中文:** 将 memory-space cast(内存空间转换)操作向下冒泡。该 pass 会尝试迭代地将所有可能的 memory-space cast 操作向下冒泡。需要注意的是,判断哪些 cast 会被向下冒泡,依据的是 MemorySpaceCastConsumerOpInterface 与 MemorySpaceCastOpInterface 这两个 interface(接口),而不是由本 pass 决定;本 pass 只是查找实现了 MemorySpaceCastConsumerOpInterface 接口的操作,并调用其接口方法来执行向下冒泡。 **Example / 示例:** ```mlir func.func @op_with_cast_sequence(%arg0: memref<4x4xf32, 1>, %arg1: index, %arg2: f32) -> memref<16xf32> { %memspacecast = memref.memory_space_cast %arg0 : memref<4x4xf32, 1> to memref<4x4xf32> %c0 = arith.constant 0 : index %c4 = arith.constant 4 : index %expanded = memref.expand_shape %memspacecast [[0], [1, 2]] output_shape [4, 2, 2] : memref<4x4xf32> into memref<4x2x2xf32> %collapsed = memref.collapse_shape %expanded [[0, 1, 2]] : memref<4x2x2xf32> into memref<16xf32> %loaded = memref.load %collapsed[%c0] : memref<16xf32> %added = arith.addf %loaded, %arg2 : f32 memref.store %added, %collapsed[%c0] : memref<16xf32> %atomic_result = memref.atomic_rmw addf %arg2, %collapsed[%c4] : (f32, memref<16xf32>) -> f32 return %collapsed : memref<16xf32> } // mlir-opt --bubble-down-memory-space-casts func.func @op_with_cast_sequence(%arg0: memref<4x4xf32, 1>, %arg1: index, %arg2: f32) -> memref<16xf32> { %c4 = arith.constant 4 : index %c0 = arith.constant 0 : index %expand_shape = memref.expand_shape %arg0 [[0], [1, 2]] output_shape [4, 2, 2] : memref<4x4xf32, 1> into memref<4x2x2xf32, 1> %collapse_shape = memref.collapse_shape %expand_shape [[0, 1, 2]] : memref<4x2x2xf32, 1> into memref<16xf32, 1> %memspacecast = memref.memory_space_cast %collapse_shape : memref<16xf32, 1> to memref<16xf32> %0 = memref.load %collapse_shape[%c0] : memref<16xf32, 1> %1 = arith.addf %0, %arg2 : f32 memref.store %1, %collapse_shape[%c0] : memref<16xf32, 1> %2 = memref.atomic_rmw addf %arg2, %collapse_shape[%c4] : (f32, memref<16xf32, 1>) -> f32 return %memspacecast : memref<16xf32> } ``` ### -canonicalize **EN:** Canonicalize operations **中文:** 规范化操作(Canonicalize operations) **EN:** This pass performs various types of canonicalizations over a set of operations by iteratively applying the canonicalization patterns of all loaded dialects until either a fixpoint is reached or the maximum number of iterations/rewrites is exhausted. Canonicalization is best-effort and does not guarantee that the entire IR is in a canonical form after running this pass. See Operation Canonicalization for more details. **中文:** 该 pass 通过迭代地应用所有已加载 dialect(方言)的规范化 pattern,对一组操作执行各种类型的规范化(canonicalization),直到达到不动点(fixpoint)或耗尽最大迭代次数/重写次数为止。规范化是尽力而为(best-effort)的,不保证运行本 pass 之后整个 IR 都处于规范形式。更多细节请参阅 Operation Canonicalization(操作规范化)。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-top-down` | Seed the worklist in general top-down order | 以自顶向下的顺序填充工作队列(worklist) | | `-region-simplify` | Perform control flow optimizations to the region tree | 对区域树(region tree)执行控制流优化 | | `-max-iterations` | Max. iterations between applying patterns / simplifying regions | 在应用 pattern / 简化 region 之间的最大迭代次数 | | `-max-num-rewrites` | Max. number of pattern rewrites within an iteration | 单次迭代内 pattern 重写的最大数量 | | `-test-convergence` | Test only: Fail pass on non-convergence to detect cyclic pattern | 仅用于测试:在因循环 pattern 而不收敛时使 pass 失败 | | `-cse-between-iterations` | Run full CSE between each pattern-application iteration. CSEdriven changes trigger extra iterations, so this may push the iteration count up to maxiterations and affect convergence under test-convergence. | 在每次 pattern 应用迭代之间运行完整 CSE。由 CSE 驱动的变更会触发额外迭代,因此可能使迭代次数逼近最大迭代次数(max-iterations),并影响 test-convergence 下的收敛性 | | `-filter-dialects` | If non-empty, only collect canonicalization patterns from the dialects with the given namespaces. The listed dialects are force-loaded into the context as dependent dialects. | 若非空,则只从具有给定命名空间的方言中收集规范化 pattern;所列方言会被作为依赖方言强制加载到上下文中 | | `-disable-patterns` | Labels of patterns that should be filtered out during application | 在应用期间应被过滤掉的 pattern 的标签(label) | | `-enable-patterns` | Labels of patterns that should be used during application, all other patterns are filtered out | 在应用期间应使用的 pattern 的标签,其余所有 pattern 都会被过滤掉 | ### -composite-fixed-point-pass **EN:** Composite fixed point pass **中文:** 组合不动点 pass(Composite fixed point pass) **EN:** Composite pass runs provided set of passes until fixed point or maximum number of iterations reached. **中文:** 组合 pass 会运行所提供的 pass 集合,直到达到不动点(fixed point)或最大迭代次数为止。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-name` | Composite pass display name | 组合 pass 的显示名称 | | `-pipeline` | Composite pass inner pipeline | 组合 pass 的内部 pipeline(流水线) | | `-max-iterations` | Maximum number of iterations if inner pipeline | 内部 pipeline 的最大迭代次数 | ### -control-flow-sink **EN:** Sink operations into conditional blocks **中文:** 将操作下沉到条件分支块中(Sink operations into conditional blocks) **EN:** This pass implements control-flow sink on operations that implement RegionBranchOpInterface by moving dominating operations whose only uses are in a conditionally-executed regions into those regions so that executions paths where their results are not needed do not perform unnecessary computations. **中文:** 该 pass 对实现了 RegionBranchOpInterface 的操作实现控制流下沉(control-flow sink):把支配(dominating)某区域、且其结果仅在该条件执行区域内被使用的操作,移动进这些区域,使得在执行到不需要其结果的路径时不会执行不必要的计算。 **EN:** This is similar (but opposite) to loop-invariant code motion, which hoists operations out of regions executed more than once. The implementation of control-flow sink uses a simple and conversative cost model: operations are never duplicated and are only moved into singly-executed regions. **中文:** 这与循环不变量代码移动(loop-invariant code motion)相似(但方向相反),后者是把操作提升到会被执行多次的区域之外。控制流下沉的实现采用了一个简单且保守的代价模型:操作永远不会被复制,也只会移动进只执行一次的区域。 **EN:** It is recommended to run canonicalization first to remove unreachable blocks: ops in unreachable blocks may prevent other operations from being sunk as they may contain uses of their results **中文:** 建议先运行规范化(canonicalization)以移除不可达的 block:不可达 block 中的操作可能阻止其他操作被下沉,因为它们可能包含对这些操作结果的使用。 **Statistics / 统计:** | Statistic | EN description | 中文说明 | |---|---|---| | `num-sunk` | Number of operations sunk | 被下沉的操作数量 | ### -cse **EN:** Eliminate common sub-expressions **中文:** 消除公共子表达式(Eliminate common sub-expressions) **EN:** This pass implements a generalized algorithm for common sub-expression elimination. This pass relies on information provided by the Memory SideEffect interface to identify when it is safe to eliminate operations. See Common subexpression elimination for more general details on this optimization. **中文:** 该 pass 实现了通用的公共子表达式消除(common sub-expression elimination)算法。它依赖 Memory SideEffect 接口提供的信息,来判断何时可以安全地消除操作。有关此优化的更一般性细节,请参阅 Common subexpression elimination(公共子表达式消除)。 **Statistics / 统计:** | Statistic | EN description | 中文说明 | |---|---|---| | `num-cse'd` | Number of operations CSE'd | 被 CSE(公共子表达式消除)的操作数量 | | `num-dce'd` | Number of operations DCE'd | 被 DCE(死代码消除)的操作数量 | ### -generate-runtime-verification **EN:** Generate additional runtime op verification checks **中文:** 生成额外的运行时操作校验检查(Generate additional runtime op verification checks) **EN:** This pass generates op-specific runtime checks using the RuntimeVerifiableOpInterface. It can be run for debugging purposes after passes that are suspected to introduce faulty IR. **中文:** 该 pass 使用 RuntimeVerifiableOpInterface 接口生成针对具体操作的运行时检查。它可以在疑似引入错误 IR 的 pass 之后运行,用于调试目的。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-verbose-level` | Verbosity level for runtime verification messages: 0 = Minimum (only source location), 1 = Detailed (include full operation details, names, types, shapes, etc.) | 运行时验证消息的详细级别:0 = 最少(仅源代码位置),1 = 详细(包含完整操作细节、名称、类型、形状等) | ### -inline **EN:** Inline function calls **中文:** 内联函数调用(Inline function calls) **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-default-pipeline` | The optimizer pipeline used for callables that do not have a dedicated optimizer pipeline in opPipelineList | 用于在 opPipelineList 中没有专用优化器 pipeline 的可调用对象的优化器 pipeline | | `-op-pipelines` | Callable operation specific optimizer pipelines (in the form of `dialect.op(pipeline)`) | 可调用操作专用的优化器 pipeline(形式为 `dialect.op(pipeline)`) | | `-max-iterations` | Maximum number of iterations when inlining within an SCC | 在 SCC(强连通分量)内进行内联时的最大迭代次数 | | `-inlining-threshold` | If the ratio between the number of the operations in the callee and the number of the operations in the caller exceeds this value (in percentage), then the callee is not inlined even if it is legal to inline it | 若被调用方中操作的数量与调用方中操作的数量的比值超过此值(以百分比计),则即使内联该被调用方是合法的,也不会对其进行内联 | ### -loop-invariant-code-motion **EN:** Hoist loop invariant instructions outside of the loop **中文:** 将循环不变(loop invariant)指令提升到循环外部。 ### -loop-invariant-subset-hoisting **EN:** Hoist loop invariant subset ops outside of the loop **中文:** 将循环不变子集操作提升到循环外部。 ### -mem2reg **EN:** Promotes memory slots into values. **中文:** 将内存槽(memory slot)提升为值。 **EN:** This pass removes loads out of and stores into a memory slot, and turns them into direct uses of SSA values. This is done generically using the PromotableAllocationOpInterface, PromotableOpInterface, PromotableMemOpInterface and PromotableRegionOpInterface interfaces. **中文:** 该 pass 移除对内存槽的 load(加载)与 store(存储),并将其转换为对 SSA 值的直接使用。这是通过 PromotableAllocationOpInterface、PromotableOpInterface、PromotableMemOpInterface 和 PromotableRegionOpInterface 这些接口通用实现的。 **EN:** This pass will attempt to compute which definitions of the content of the memory slot reach operations that use the memory slot pointer. It will rewire or remove operations that use the slot pointer so they no longer use it. If any of this is not possible, the IR will be left without mutation. **中文:** 该 pass 会尝试计算内存槽内容的哪些定义(definition)能到达使用内存槽指针的操作,并重新连接或移除使用槽指针的操作,使其不再使用该指针。如果其中任何一步无法做到,IR 将保持原样不做修改。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-region-simplify` | Perform control flow optimizations to the region tree | 对区域树(region tree)执行控制流优化 | **Statistics / 统计:** | Statistic | EN description | 中文说明 | |---|---|---| | `promoted slots` | Total amount of memory slot promoted | 被提升的内存槽总数 | | `new block args` | Total amount of new block argument inserted in blocks | 插入到 block 中的新块参数(block argument)总数 | ### -print-ir **EN:** Print IR on the debug stream **中文:** 在调试流上打印 IR(Print IR on the debug stream) **EN:** Print the entire IR on the debug stream. This is meant for debugging purposes to inspect the IR at a specific point in the pipeline. **中文:** 将整个 IR 打印到调试流(debug stream)上。其用途是调试,以便检查 pipeline(流水线)中某个特定点处的 IR。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-label` | Label | 标签(label) | ### -print-op-stats **EN:** Print statistics of operations **中文:** 打印操作的统计信息(Print statistics of operations) **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-json` | print the stats as JSON | 以 JSON 形式打印统计信息 | ### -remove-dead-values **EN:** Remove dead values **中文:** 移除无存活(non-live)值(Remove dead values) **EN:** The goal of this pass is optimization (reducing runtime) by removing unnecessary instructions. Unlike other passes that rely on local information gathered from patterns to accomplish optimization, this pass uses a full analysis of the IR, specifically, liveness analysis, and is thus more powerful. Currently, this pass performs the following optimizations: (A) Removes function arguments that are not live, (B) Removes function return values that are not live across all callers of the function, (C) Removes unneccesary operands, results, region arguments, and region terminator operands of region branch ops, and, (D) Removes simple and region branch ops that have all non-live results and don’t affect memory in any way. **中文:** 该 pass 的目标是通过移除不必要的指令来进行优化(减少运行时间)。与其他依赖从 pattern 中收集的局部信息来完成优化的 pass 不同,该 pass 使用对 IR 的完整分析——具体而言是存活性分析(liveness analysis)——因此更强大。目前,该 pass 执行以下优化:(A) 移除不存活的函数参数;(B) 移除在该函数的所有调用方中都不存活的函数返回值;(C) 移除 region branch op 中不必要的操作数、结果、region 参数以及 region 终止符的操作数;并且 (D) 移除所有结果都不存活且以任何方式都不影响内存的 simple op(简单操作)和 region branch op。 **EN:** Here, a “simple op” refers to an op that isn’t a symbol op, symbol-user op, region branch op, branch op, region branch terminator op, or return-like. It is noteworthy that we do not refer to non-live values as “dead” in this file to avoid confusing it with dead code analysis’s “dead”, which refers to unreachable code (code that never executes on hardware) while “non-live” refers to code that executes on hardware but is unnecessary. Thus, while the removal of dead code helps little in reducing runtime, removing non-live values should theoretically have significant impact (depending on the amount removed). It is also important to note that unlike other passes (like canonicalize ) that apply op-specific optimizations through patterns, this pass uses different interfaces to handle various types of ops and tries to cover all existing ops through these interfaces. It is because of its reliance on (a) liveness analysis and (b) interfaces that makes it so powerful that it can optimize ops that don’t have a canonicalizer and even when an op does have a canonicalizer, it can perform more aggressive optimizations, as observed in the test files associated with this pass. **中文:** 这里,“simple op”(简单操作)指的是既不是 symbol op、symbol-user op、region branch op、branch op、region branch 终止符 op,也不是 return-like(类似返回)的操作。值得注意的是,本文件中我们并不把 non-live(非存活)值称为 “dead”(死),以避免与死代码分析中的 “dead” 相混淆——后者指不可达的代码(在硬件上永远不会执行的代码),而 “non-live” 指会在硬件上执行但并非必要的代码。因此,虽然移除死代码对减少运行时间帮助有限,但从理论上说,移除 non-live 值应能产生显著效果(取决于被移除的数量)。同样重要的是要注意到:与其他通过 pattern 应用特定于操作的优化的 pass(如 canonicalize)不同,该 pass 使用不同的接口来处理各种类型的操作,并试图通过这些接口覆盖所有现存的操作。正是由于它依赖 (a) 存活性分析和 (b) 接口,才如此强大——它能优化那些没有规范化器(canonicalizer)的操作;即便某个操作有规范化器,它也能执行更激进的优化,这一点可以在与本 pass 关联的测试文件中观察到。 **Example of optimization (A) / 优化示例 (A):** ``` int add_2_to_y(int x, int y) { return 2 + y } print(add_2_to_y(3, 4)) print(add_2_to_y(5, 6)) ``` **EN:** becomes **中文:** 变为(becomes) ``` int add_2_to_y(int y) { return 2 + y } print(add_2_to_y(4)) print(add_2_to_y(6)) ``` **Example of optimization (B) / 优化示例 (B):** ``` int, int get_incremented_values(int y) { store y somewhere in memory return y + 1, y + 2 } y1, y2 = get_incremented_values(4) y3, y4 = get_incremented_values(6) print(y2) ``` **EN:** becomes **中文:** 变为(becomes) ``` int get_incremented_values(int y) { store y somewhere in memory return y + 2 } y2 = get_incremented_values(4) y4 = get_incremented_values(6) print(y2) ``` **Example of optimization (C) / 优化示例 (C):** **EN:** Assume only %result1 is live here. Then, **中文:** 假设此处只有 %result1 是存活的(live)。那么, ```mlir %result1, %result2, %result3 = scf.while (%arg1 = %operand1, %arg2 = %operand2) { %terminator_operand2 = add %arg2, %arg2 %terminator_operand3 = mul %arg2, %arg2 %terminator_operand4 = add %arg1, %arg1 scf.condition(%terminator_operand1) %terminator_operand2, %terminator_operand3, %terminator_operand4 } do { ^bb0(%arg3, %arg4, %arg5): %terminator_operand6 = add %arg4, %arg4 %terminator_operand5 = add %arg5, %arg5 scf.yield %terminator_operand5, %terminator_operand6 } ``` **EN:** becomes **中文:** 变为(becomes) ```mlir %result1, %result2 = scf.while (%arg2 = %operand2) { %terminator_operand2 = add %arg2, %arg2 %terminator_operand3 = mul %arg2, %arg2 scf.condition(%terminator_operand1) %terminator_operand2, %terminator_operand3 } do { ^bb0(%arg3, %arg4): %terminator_operand6 = add %arg4, %arg4 scf.yield %terminator_operand6 } ``` **EN:** It is interesting to see that %result2 won’t be removed even though it is not live because %terminator_operand3 forwards to it and cannot be removed. And, that is because it also forwards to %arg4 , which is live. **中文:** 有趣的是,%result2 虽然不存活却不会被移除,因为 %terminator_operand3 转发(forward)到它且无法被移除;而这是因为它还转发到存活的 %arg4。 **Example of optimization (D) / 优化示例 (D):** ``` int square_and_double_of_y(int y) { square = y ^ 2 double = y * 2 return square, double } sq, do = square_and_double_of_y(5) print(do) ``` **EN:** becomes **中文:** 变为(becomes) ``` int square_and_double_of_y(int y) { double = y * 2 return double } do = square_and_double_of_y(5) print(do) ``` **EN:** Note: If canonicalize is set to “false”, this pass does not remove any block arguments / op results from ops that implement the RegionBranchOpInterface. Instead, it just sets dead operands to “ub.poison”. **中文:** 注意:如果将 canonicalize 设为 “false”,该 pass 不会从实现了 RegionBranchOpInterface 的操作中移除任何块参数 / 操作结果,而是仅仅把死操作数设置为 “ub.poison”。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-canonicalize` | Canonicalize region branch ops | 对 region branch op 进行规范化(canonicalize) | --- ### -sccp **EN:** Sparse Conditional Constant Propagation This pass implements a general algorithm for sparse conditional constant propagation. This algorithm detects values that are known to be constant and optimistically propagates this throughout the IR. Any values proven to be constant are replaced, and removed if possible. This implementation is based on the algorithm described by Wegman and Zadeck in “Constant Propagation with Conditional Branches” (1991). **中文:** 稀疏条件常量传播(Sparse Conditional Constant Propagation) 本 pass 实现了一个通用的稀疏条件常量传播算法。该算法检测已知为常量的值,并乐观地将其在整个 IR 中传播。任何被证明为常量的值都会被替换,并在可能的情况下删除。 本实现基于 Wegman 和 Zadeck 在 “Constant Propagation with Conditional Branches”(1991)一文中描述的算法。 ### -snapshot-op-locations **EN:** Generate new locations from the current IR This pass allows for generating new locations from the IR during any stage of compilation, by snapshotting the IR to a file and using that file to generate new locations for the operations. Depending on the value of the tag option, different resulting locations may be generated: If unset, the original location of the operation is replaced. **中文:** 从当前 IR 生成新的位置(location) 本 pass 允许在编译的任何阶段从 IR 生成新的 location:它将 IR 快照(snapshot)到一个文件,并使用该文件为各个操作(operation)生成新的 location。 根据 tag 选项的取值,可能生成不同的结果 location: 若未设置,则操作的原始 location 会被替换。 **Example / 示例:** ```mlir // old: ... loc("original_source.cpp":1:1) // new: ... loc("snapshot_source.mlir":10:10) ``` **EN:** If set, the new location is fused with the original location in the form of a Name Location with the specified tag. **中文:** 若已设置,则新的 location 会以带有指定 tag 的 Name Location(名称位置)形式与原始 location 融合(fuse)。 **Example / 示例:** ```mlir // old: ... loc("original_source.cpp":1:1) // new: ... loc(fused["original_source.cpp":1:1, "snapshot"("snapshot_source.mlir":10:10)]) ``` **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-filename` | The filename to print the generated IR | 用于打印生成的 IR 的文件名 | | `-tag` | A tag to use when fusing the new locations with the original. If unset, the locations are replaced. | 将新的 location 与原始 location 融合时使用的 tag。若未设置,则直接替换 location。 | | `-print-debuginfo` | Print debug info in MLIR output | 在 MLIR 输出中打印调试信息(debug info) | | `-print-op-generic` | Print the generic op form | 打印操作的通用形式(generic op form) | | `-print-local-scope` | Print with local scope and inline information (eliding aliases for attributes, types, and locations | 以局部作用域和内联信息进行打印(省略 attribute、type 和 location 的别名) | | `-pretty-debuginfo` | Print pretty debug info in MLIR output | 在 MLIR 输出中打印美化的调试信息 | ### -sroa **EN:** Scalar Replacement of Aggregates Scalar Replacement of Aggregates. Replaces allocations of aggregates into independant allocations of its elements. Allocators must implement DestructurableAllocationOpInterface to provide the list of memory slots for which destructuring should be attempted. **中文:** 聚合体的标量替换(Scalar Replacement of Aggregates) 对聚合体(aggregate)进行标量替换。将聚合体的分配替换为其各元素的独立分配。 分配器(allocator)必须实现 DestructurableAllocationOpInterface,以提供应尝试解构(destructuring)的内存槽(memory slot)列表。 **EN:** This pass will only be applied if all accessors of the aggregate implement the DestructurableAccessorOpInterface . If the accessors provide a view into the struct, users of the view must ensure it is used in a type-safe manner and within bounds by implementing TypeSafeOpInterface . **中文:** 只有当聚合体的所有访问器(accessor)都实现了 DestructurableAccessorOpInterface 时,本 pass 才会被应用。如果这些访问器提供了对结构体(struct)的视图(view),则视图的使用者必须通过实现 TypeSafeOpInterface 来确保该视图以类型安全的方式在边界范围内使用。 **Statistics / 统计:** | Statistic | EN description | 中文说明 | |---|---|---| | `destructured slots` | Total amount of memory slots destructured | 被解构的内存槽总数 | | `slots with memory benefit` | Total amount of memory slots in which the destructured size was smaller than the total size after eliminating unused fields | 在消除未使用字段后,解构后的尺寸小于总尺寸的内存槽数量 | | `max subelement number` | Maximal number of sub-elements a successfully destructured slot initially had | 成功解构的内存槽最初拥有的子元素(sub-element)最大数量 | ### -strip-debuginfo **EN:** Strip debug info from all operations This pass strips the IR of any location information, by replacing all operation locations with unknown . **中文:** 从所有操作中剥离调试信息 本 pass 通过将所有操作的 location 替换为 unknown,从而去除 IR 中的任何位置(location)信息。 ### -symbol-dce **EN:** Eliminate dead symbols This pass deletes all symbols that are found to be unreachable. This is done by computing the set of operations that are known to be live, propagating that liveness to other symbols, and then deleting all symbols that are not within this live set. Live symbols are those that have a visibility that extends beyond the IR, e.g. public , or those that are referenced by live symbols or other non-Symbol operations. For example, consider the following input: **中文:** 消除死符号(dead symbols) 本 pass 删除所有被判定为不可达的 symbol。其做法是:先计算出已知存活(live)的操作集合,将该存活性传播到其他 symbol,然后删除不在此存活集合中的所有 symbol。存活的 symbol 是指可见性(visibility)超出当前 IR 的 symbol(例如 public),或者被存活的 symbol 或其他非 Symbol 操作所引用的 symbol。 例如,考虑以下输入: ```mlir func.func private @dead_private_function() func.func private @live_private_function() // Note: The `public` isn't necessary here, as this is the default. func.func public @public_function() { "foo.return"() {uses = [@live_private_function]} : () -> () } ``` **EN:** A known live function, public_function , contains a reference to an otherwise non-live function live_private_function . After running symbol-dce , only these two symbols should remain, as the final symbol dead_private_function is not visible outside of the current IR and there are no links to known-live operations. After running, we get the expected: **中文:** 已知存活的函数 public_function 引用了另一个本不存活的函数 live_private_function。运行 symbol-dce 之后,应当只剩下这两个 symbol,因为符号 dead_private_function 在当前 IR 之外不可见,也没有任何指向已知存活操作的链接。 运行后得到预期的结果: ```mlir func.func private @live_private_function() func.func public @public_function() { "foo.return"() {uses = [@live_private_function]} : () -> () } ``` **EN:** See Symbols and SymbolTables for more information on Symbols . **中文:** 有关 symbol 的更多信息,请参阅 Symbols 和 SymbolTables。 **Statistics / 统计:** | Statistic | EN description | 中文说明 | |---|---|---| | `num-dce'd` | Number of symbols DCE'd | 被 DCE(死代码消除)掉的 symbol 数量 | ### -symbol-privatize **EN:** Mark symbols private This pass marks all top-level symbols of the operation run as private except if listed in exclude pass option. **中文:** 将符号标记为私有(private) 本 pass 将本次运行中操作的所有顶层 symbol 标记为 private,除非它们列在 exclude pass 选项中。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-exclude` | Comma separated list of symbols that should not be marked private | 不应被标记为 private 的、以逗号分隔的 symbol 列表 | ### -topological-sort **EN:** Sort regions without SSA dominance in topological order Recursively sorts all nested regions without SSA dominance in topological order. The main purpose is readability, as well as potentially processing of certain transformations and analyses. The function sorts the operations in all nested regions such that, as much as possible, all users appear after their producers. **中文:** 按拓扑顺序对没有 SSA 支配关系的 region 进行排序 递归地按照拓扑顺序(topological order)对所有没有 SSA 支配关系(SSA dominance)的嵌套 region 进行排序。其主要目的是提高可读性,同时便于某些变换和分析的处理。该函数会对所有嵌套 region 中的操作进行排序,使尽可能多的使用者(user)出现在其生产者(producer)之后。 **EN:** This sort is stable. If the block is already topologically sorted, the IR is not changed. Operations that form a cycle are moved to the end of the regions in a stable order. **中文:** 该排序是稳定的(stable)。如果 block 已经按拓扑顺序排好,则 IR 保持不变。构成环(cycle)的操作会以稳定顺序移动到 region 的末尾。 ### -trivial-dce **EN:** Remove trivially dead operations and blocks This pass eliminates only trivially dead operations; that is, side-effect-free operations with no users. By default, it also removes trivially dead blocks; that is, blocks that are unreachable from their region entry block. The removeblocks option can be disabled to preserve unreachable blocks. This pass does not run a liveness analysis and does not remove dead use-def cycles. By default, this pass recursively visits nested regions. The recursive option can be disabled to restrict the pass to only the immediate regions nested under the current operation. **中文:** 删除平凡死(trivially dead)的操作和 block 本 pass 只消除平凡死的操作,即没有使用者且无副作用(side-effect-free)的操作。默认情况下,它还会删除平凡死的 block,即从其 region 入口 block(entry block)不可达的 block。可以禁用 removeblocks 选项以保留不可达的 block。 本 pass 不运行存活性分析(liveness analysis),也不删除死的使用-定义(use-def)环。 默认情况下,本 pass 递归访问嵌套 region。可以禁用 recursive 选项,将本 pass 限制为仅处理当前操作直接之下的嵌套 region。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-recursive` | Recursively visit nested regions | 递归访问嵌套 region | | `-remove-blocks` | Remove unreachable blocks | 删除不可达的 block | ### -view-op-graph **EN:** Print Graphviz visualization of an operation This pass prints a Graphviz graph of a module. Operations are represented as nodes; Uses (data flow) as edges; Control flow as dashed edges; Regions/blocks as subgraphs. By default, only data flow edges are printed. Note: See https://www.graphviz.org/doc/info/lang.html for more information about the Graphviz DOT language. **中文:** 打印操作的 Graphviz 可视化 本 pass 打印一个 module 的 Graphviz 图。 操作表示为节点(node); 使用(use,数据流)表示为边(edge); 控制流表示为虚线边; region/block 表示为子图(subgraph)。 默认情况下,只打印数据流边。 注意:有关 Graphviz DOT 语言的更多信息,请参阅 https://www.graphviz.org/doc/info/lang.html 。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-max-label-len` | Limit attribute/type length to number of chars | 将 attribute/type 的长度限制为指定字符数 | | `-print-attrs` | Print attributes of operations | 打印操作的属性(attribute) | | `-print-control-flow-edges` | Print control flow edges | 打印控制流边 | | `-print-data-flow-edges` | Print data flow edges | 打印数据流边 | | `-print-result-types` | Print result types of operations | 打印操作的结果类型(result type) | --- ## Bufferization Passes(缓冲化 Pass) ### -buffer-deallocation-simplification **EN:** Optimizes bufferization.dealloc operation for more efficient codegen **中文:** 优化 bufferization.dealloc 操作,以获得更高效的代码生成(codegen)。 **EN:** This pass uses static alias analysis to reduce the number of alias checks required at runtime. Such checks are sometimes necessary to make sure that memrefs aren’t deallocated before their last usage (use after free) or that some memref isn’t deallocated twice (double free). **中文:** 该 Pass 使用静态别名分析(static alias analysis)来减少运行时所需的别名检查数量。这些检查有时是必要的,用于确保 memref 不会在其最后一次使用之前被释放(use after free),也不会导致某个 memref 被释放两次(double free)。 ### -buffer-hoisting **EN:** Optimizes placement of allocation operations by moving them into common dominators and out of nested regions **中文:** 通过将分配操作移入公共支配者(common dominator)并移出嵌套区域,来优化其放置位置。 **EN:** This pass implements an approach to aggressively move allocations upwards into common dominators and out of nested regions. **中文:** 该 Pass 实现了一种方法,激进地将分配向上移入公共支配者并移出嵌套区域。 ### -buffer-loop-hoisting **EN:** Optimizes placement of allocation operations by moving them out of loop nests **中文:** 通过将分配操作移出循环嵌套(loop nest)来优化其放置位置。 **EN:** This pass implements an approach to aggressively move allocations upwards out of loop nests. It does not move allocations into common dominators. **中文:** 该 Pass 实现了一种方法,激进地将分配向上移出循环嵌套。它不会将分配移入公共支配者。 ### -buffer-results-to-out-params **EN:** Converts memref-typed function results to out-params **中文:** 将 memref 类型的函数返回值转换为输出参数(out-param)。 **EN:** Some calling conventions prefer to pass output memrefs as “out params”. The conversion to this calling convention must be done as an atomic transformation of the entire program (hence this is a module pass). **中文:** 某些调用约定倾向于将输出 memref 作为“输出参数(out param)”传递。向该调用约定的转换必须作为对整个程序的原子变换来完成(因此这是一个 module Pass)。 **EN:** For example, if a call is rewritten, the callee needs to be rewritten otherwise the IR will end up invalid. Thus, this transformation require an atomic change to the entire program (e.g. the whole module). **中文:** 例如,如果一个调用被重写,那么被调用函数也需要被重写,否则 IR 最终会变为非法。因此,该变换要求对整个程序(例如整个 module)进行原子修改。 **EN:** This pass is expected to run immediately after bufferization is finished. At that point, tensor-typed results will have been converted to memref-typed results, and can be consistently converted to out params. **中文:** 预期该 Pass 在缓冲化(bufferization)完成之后立即运行。此时,tensor 类型的返回值已被转换为 memref 类型的返回值,并且可以一致地将其转换为输出参数。 **EN:** All memref-typed results are appended to the function argument list. **中文:** 所有 memref 类型的返回值都会被追加到函数参数列表中。 **EN:** The main issue with this pass (and the out-param calling convention) is that buffers for results need to be allocated in the caller. This currently only works for static shaped memrefs. **中文:** 该 Pass(以及输出参数调用约定)的主要问题是,返回值的缓冲需要在调用方分配。目前这只对静态形状(static shaped)的 memref 有效。 **EN:** If the hoist-static-allocs option is on, the pass tries to eliminate the allocation for the returned memref and avoid the memory-copy if possible. This optimization applies on the returned memref which has static shape and is allocated by memref.alloc in the function. It will use the memref given in function argument to replace the allocated memref. **中文:** 如果开启 hoist-static-allocs 选项,该 Pass 会尝试消除对返回 memref 的分配,并在可能时避免内存拷贝。该优化适用于具有静态形状、且在函数内部由 memref.alloc 分配的返回 memref;它将使用作为函数参数传入的 memref 来替换所分配的 memref。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-add-result-attr` | Add the attribute 'bufferize.result' to all output parameters. | 为所有输出参数添加 'bufferize.result' 属性。 | | `-hoist-static-allocs` | Hoist static allocations to call sites. | 将静态分配提升到调用点(call site)。 | | `-hoist-dynamic-allocs` | Hoist dynamic allocations to call sites. | 将动态分配提升到调用点。 | | `-modify-public-functions` | Modify function signatures of public functions. | 修改公共函数的函数签名。 | ### -bufferization-lower-deallocations **EN:** Lowers bufferization.dealloc operations to memref.dealloc operations **中文:** 将 bufferization.dealloc 操作降级(lower)为 memref.dealloc 操作。 **EN:** This pass lowers bufferization.dealloc operations to the memref dialect. It can be applied to a builtin.module or operations implementing the FunctionOpInterface. For the latter, only simple dealloc operations can be lowered because the library function necessary for the fully generic lowering cannot be inserted. In this case, an error will be emitted. Next to memref.dealloc operations, it may also emit operations from the arith, scf, and func dialects to build conditional deallocations and library functions to avoid codesize blow-up. **中文:** 该 Pass 将 bufferization.dealloc 操作降级到 memref 方言。它可以应用于 builtin.module,或实现 FunctionOpInterface 的操作。对于后者,只能降级简单的 dealloc 操作,因为完全通用降级所需的库函数无法被插入;在这种情况下会发出错误。除了 memref.dealloc 操作外,它还可能发射来自 arith、scf 和 func 方言的操作来构建条件释放(conditional deallocation)以及库函数,以避免代码体积膨胀(codesize blow-up)。 ### -drop-equivalent-buffer-results **EN:** Remove MemRef return values that are equivalent to a bbArg **中文:** 移除与 bbArg 等价的 MemRef 返回值。 **EN:** This pass removes MemRef return values from functions if they are equivalent to a function bbArg. In that case, the return value is redundant and the respective CallOp operand can be used at the call site. **中文:** 如果函数的 MemRef 返回值与某个函数 bbArg(块参数)等价,该 Pass 会将其移除。在这种情况下,该返回值是冗余的,可以在调用点直接使用相应 CallOp 的操作数。 **EN:** Note: If a bbArg buffer is not returned directly but casted to beforehand, the buffer is still considered equivalent. **中文:** 注意:如果某个 bbArg 缓冲不是被直接返回、而是先经过转换(cast)再返回,该缓冲仍被视为等价。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-modify-public-functions` | Modify function signatures of public functions. | 修改公共函数的函数签名。 | ### -eliminate-empty-tensors **EN:** Try to eliminate all tensor.empty ops. **中文:** 尝试消除所有 tensor.empty 操作。 **EN:** Try to eliminate “tensor.empty” ops inside op . This transformation looks for subset ops that insert a tensor that originates from a “tensor.empty” (as per the reverse use-def chain). Such “tensor.empty” ops are replaced with the destination subset. **中文:** 尝试消除 op 内部的 “tensor.empty” 操作。该变换查找那些插入源自某个 “tensor.empty”(按反向 use-def 链)的 tensor 的子集(subset)操作;这样的 “tensor.empty” 操作会被目标子集替换。 **E.g. / 例如:** ```mlir %0 = tensor.empty() : tensor<10xf32> %1 = linalg.fill ... outs(%0 : tensor<10xf32>) %2 = tensor.insert_slice %1 into %t ... ``` **EN:** In the above example, the subset op is “tensor.insert_slice”. When tracing back the reverse use-def chain of a the source, we end up at a “tensor.empty” op. The “tensor.empty” op is replaced with a “tensor.extract_slice” op. **中文:** 在上面的例子中,子集操作是 “tensor.insert_slice”。沿着源的(source)反向 use-def 链回溯,最终会到达一个 “tensor.empty” 操作;该 “tensor.empty” 操作会被替换为一个 “tensor.extract_slice” 操作。 ### -empty-tensor-to-alloc-tensor **EN:** Replace all empty ops by alloc_tensor ops. **中文:** 用 alloc_tensor 操作替换所有 empty 操作。 **EN:** tensor.empty ops return a tensor of unspecified contents who’s only purpose is to carry the tensor shape. This pass converts such ops to bufferization.alloc_tensor ops, which bufferize to buffer allocations. **中文:** tensor.empty 操作返回内容未指定的 tensor,其唯一目的是承载 tensor 的形状。该 Pass 将这类操作转换为 bufferization.alloc_tensor 操作,后者会缓冲化为缓冲分配(buffer allocation)。 ### -one-shot-bufferize **EN:** One-Shot Bufferize **中文:** One-Shot Bufferize(一次性缓冲化) **EN:** This pass bufferizes all ops that implement BufferizableOpInterface. It first performs an inplacability analysis on SSA use-def chains of tensor values to determine which OpOperands may bufferize in-place, i.e., without inserting a buffer copy. It then rewrites the IR, inserting a buffer allocation and copy for each OpOperand that was decided to bufferize out-of-place. **中文:** 该 Pass 对所有实现 BufferizableOpInterface 的 op 进行缓冲化。它首先对 tensor 值的 SSA use-def 链执行 in-placability(就地性)分析,以确定哪些 OpOperand 可以原地(in-place)缓冲化,即无需插入缓冲拷贝;然后重写 IR,为每个被判定为非原地(out-of-place)缓冲化的 OpOperand 插入一个缓冲分配和一次拷贝。 **EN:** One-Shot Bufferize (and BufferizableOpInterface) was designed for ops that are in destination-passing style. When bufferizing such ops, it is possible to reuse the buffer of a tensor OpOperand for a tensor OpResult. In essence, a possible destination of an operation is already passed as an SSA value. **中文:** One-Shot Bufferize(以及 BufferizableOpInterface)是为目的地址传递风格(destination-passing style)的 op 设计的。缓冲化这类 op 时,可以复用某个 tensor OpOperand 的缓冲作为 tensor OpResult 的缓冲;本质上,一个操作的可能目的地已经作为一个 SSA 值被传入。 **EN:** tensor.insert is an example for an op in destination-passing style. E.g., when bufferizing %t0 = tensor.insert %f into %dest[%idx], buffer(%t0) is identical to buffer(%dest) in the absence of RaW conflicts. As a counter example, tensor.generate is not in destination-passing style and always results in a new buffer allocation. **中文:** tensor.insert 就是一个目的地址传递风格 op 的例子。例如,在缓冲化 %t0 = tensor.insert %f into %dest[%idx] 时,若不存在 RaW(读后写)冲突,则 buffer(%t0) 与 buffer(%dest) 相同。作为反例,tensor.generate 不是目的地址传递风格,总是产生一次新的缓冲分配。 **EN:** One-Shot Bufferize does not deallocate any buffers that it allocates. The -buffer-deallocation-pipeline pipeline should be run after One-Shot Bufferize to insert the deallocation operations necessary to eliminate memory leaks. **中文:** One-Shot Bufferize 不会释放它所分配的任何缓冲。应在 One-Shot Bufferize 之后运行 -buffer-deallocation-pipeline 流水线(pipeline),以插入消除内存泄漏所需的释放操作。 **EN:** One-Shot Bufferize will by default reject IR that contains non-bufferizable op, i.e., ops that do not implemement BufferizableOpInterface. Such IR can be allowed with allow-unknown-ops=1. In that case, to_buffer and to_tensor ops will be generated at the bufferization boundary. This is useful for compatibility with existing partial bufferization passes: These can bufferize the remaining IR after running One-Shot Bufferize. **中文:** 默认情况下,One-Shot Bufferize 会拒绝包含不可缓冲化 op(即未实现 BufferizableOpInterface 的 op)的 IR。使用 allow-unknown-ops=1 可以允许这样的 IR;此时会在缓冲化边界处生成 to_buffer 和 to_tensor 操作。这对与现有部分缓冲化 Pass 保持兼容很有用:这些 Pass 可以在运行 One-Shot Bufferize 之后对剩余 IR 进行缓冲化。 **EN:** Note: Running One-Shot Bufferize after a partial bufferization pass is currently not supported. Running partial bufferization passes after running One-Shot Bufferize is supported and the recommended way to gradually migrate from partial bufferization to One-Shot Bufferize. **中文:** 注意:目前不支持在部分缓冲化 Pass 之后运行 One-Shot Bufferize。在运行 One-Shot Bufferize 之后再运行部分缓冲化 Pass 是受支持的,也是从部分缓冲化逐步迁移到 One-Shot Bufferize 的推荐方式。 **EN:** With dialect-filter, bufferization can be restricted to a set of dialects. If no filter is specified, all ops that implement BufferizableOpInterface are bufferized. Ops from the std dialect are an exception: These ops are always ignored, even if no filter is specified. When specifying a dialect filter and allow-unknown-ops is not turned on, bufferization would fail when encountering an op that is not included in the filter (even if it is bufferizable). **中文:** 通过 dialect-filter,缓冲化可以被限制到一组方言。如果没有指定过滤条件,则所有实现 BufferizableOpInterface 的 op 都会被缓冲化。std 方言的 op 是例外:这些 op 总是被忽略,即使没有指定过滤条件也是如此。当指定了方言过滤且未开启 allow-unknown-ops 时,遇到一个不在过滤范围内的 op(即使它是可缓冲化的)会导致缓冲化失败。 **EN:** One-Shot Bufferize will by default assume memref types with fully dynamic layout maps when a precise layout cannot be inferred. E.g., this is the case when wrapping a non-bufferizable op in to_buffer/to_tensor ops. This behavior can be overridden with unknown-type-conversion. Valid values are fully-dynamic-layout-map and identity-layout-map. **中文:** 当无法推断精确布局时,One-Shot Bufferize 默认假定 memref 类型带有完全动态的布局映射(layout map)。例如,用 to_buffer/to_tensor 操作包裹一个不可缓冲化 op 时就属于这种情况。该行为可以用 unknown-type-conversion 覆盖,有效取值为 fully-dynamic-layout-map 和 identity-layout-map。 **EN:** For testing/debugging purposes, test-analysis-only=1 print-conflicts=1 prints analysis results and explains why an OpOperand was decided to bufferize out-of-place. This is useful for understanding why OneShot Bufferize chose to insert a certain buffer copy. **中文:** 出于测试/调试目的,test-analysis-only=1 print-conflicts=1 会打印分析结果,并解释某个 OpOperand 为何被判定为非原地缓冲化。这有助于理解 OneShot Bufferize 为何选择插入某次缓冲拷贝。 **EN:** bufferize-function-boundaries is an experimental flag for bufferizing FuncOp, ReturnOp and CallOp. This feature is still under development and supports only simple cases at the moment. In particular: **中文:** bufferize-function-boundaries 是一个用于缓冲化 FuncOp、ReturnOp 和 CallOp 的实验性标志。该功能仍在开发中,目前仅支持简单情形。具体而言: - **EN:** Recursive or circular function call graphs are not supported. **中文:** 不支持递归或循环的函数调用图。 - **EN:** External functions (without bodies) that return a tensor are not supported. **中文:** 不支持返回 tensor 的外部函数(没有函数体)。 - **EN:** Function with multiple blocks or multiple ReturnOps are not supported. **中文:** 不支持具有多个块或多个 ReturnOp 的函数。 **EN:** Layout maps on function signatures can be controlled with a separate function-boundary-typeconversion option, which is similar to unknown-type-conversion but supports an additional inferlayout-map option. fully-dynamic-layout-map and identity-layout-map ensure that function signatures bufferize to easily predictable types, potentially at the cost of additional casts and copies, respectively. When layout maps are inferred, function return types may be more precise, but less predictable. Function argument types cannot be inferred and always have fully dynamic layout maps with infer-layout-map. **中文:** 函数签名上的布局映射可以通过单独的 function-boundary-typeconversion 选项来控制,它与 unknown-type-conversion 类似,但额外支持 inferlayout-map 选项。fully-dynamic-layout-map 和 identity-layout-map 分别确保函数签名缓冲化为易于预测的类型,可能以额外的转换(cast)和拷贝为代价。当布局映射被推断时,函数返回类型可能更精确,但可预测性更低;而函数参数类型无法被推断,使用 infer-layout-map 时始终带有完全动态的布局映射。 **EN:** One-Shot Bufferize implements the following contract around function calls: The buffer of function arguments is always writable (unless annotated with bufferization.writable = false). A buffer copy may be inserted at the call site where necessary. Alias sets and equivalence info is propagated through function calls. Whenever a function is bufferized, all other functions that are being called were already analyzed and bufferized, so exact alias and equivalence information is available. This is why recursive function calls are not yet supported. **中文:** One-Shot Bufferize 围绕函数调用实现了如下约定:函数参数的缓冲总是可写的(除非被标注为 bufferization.writable = false);必要时可以在调用点插入缓冲拷贝。别名集(alias set)和等价性信息会穿过函数调用进行传播。每当一个函数被缓冲化时,所有它调用的其他函数都已经被分析和缓冲化过,因此精确的别名与等价信息是可用的。这就是目前尚不支持递归函数调用的原因。 **EN:** One-Shot Bufferize gathers additional information during the analysis phase when function boundary bufferization is activated. E.g., whether a function argument is read/written and which returned values are aliasing/equivalent. For debugging purposes, such information can be printed with test-analysis-only. **中文:** 当函数边界缓冲化被激活时,One-Shot Bufferize 会在分析阶段收集额外信息。例如:某个函数参数是被读还是被写,以及哪些返回值之间存在别名/等价关系。出于调试目的,可以用 test-analysis-only 打印这类信息。 **EN:** The order in which ops are analyzed is important. The analysis is greedy and ops that are analyzed earlier are more likely to bufferize in-place. The heuristic can be set with analysis-heuristic. At the moment, the following heuristics are available: **中文:** op 被分析的顺序很重要。该分析是贪心的,越早被分析的 op 越可能原地缓冲化。启发式策略可以用 analysis-heuristic 设置。目前可用的启发式有: - **EN:** bottom-up (default): Analyze ops from bottom to top. **中文:** bottom-up(默认):自底向上分析 op。 - **EN:** top-down: Analyze ops from top to bottom. **中文:** top-down:自顶向下分析 op。 - **EN:** fuzzer: Randomize the ordering of ops with analysis-fuzzer-seed. **中文:** fuzzer:用 analysis-fuzzer-seed 随机化 op 的顺序。 - **EN:** bottom-up-from-terminators: Traverse the reverse use-def chains of tensor IR, starting from region branch terminators (bottom-up). Nested regions are traversed before enclosing regions. Analyze the traversed ops first, then analyze the remaining ops bottom-up. This heuristic is useful for bufferizing loop constructs. One-Shot Bufferize currently supports only such IR where yielded tensor values bufferize to equivalent region iter_args, and first analyzing all ops on the path from the “yielding” op to the beginning of the loop body makes it more likely for the region iter_args and yielded values to bufferize to equivalent buffers. **中文:** bottom-up-from-terminators:从区域分支终结符(region branch terminator)出发,遍历 tensor IR 的反向 use-def 链(自底向上)。嵌套区域先于其外层区域被遍历。先分析被遍历到的 op,再自底向上分析其余的 op。该启发式对缓冲化循环构造很有用。One-Shot Bufferize 目前仅支持那种产出的(yielded)tensor 值会缓冲化为等价 region iter_args 的 IR;并且,先分析从“产出”op 到循环体开头路径上的所有 op,会使 region iter_args 与产出值更可能缓冲化为等价的缓冲。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-allow-return-allocs-from-loops` | Allows returning/yielding new allocations from a loop. | 允许从循环中返回/产出新的分配。 | | `-allow-unknown-ops` | Allows unknown (not bufferizable) ops in the input IR. | 允许输入 IR 中存在未知(不可缓冲化)的 op。 | | `-analysis-fuzzer-seed` | Test only: Analyze ops in random order with a given seed (fuzzer) | 仅测试用:以给定种子随机顺序分析 op(fuzzer)。 | | `-analysis-heuristic` | Heuristic that control the IR traversal during analysis | 控制分析期间 IR 遍历的启发式策略。 | | `-bufferize-function-boundaries` | Bufferize function boundaries (experimental). | 缓冲化函数边界(实验性)。 | | `-check-parallel-regions` | Account for parallel regions in RaW analysis. | 在 RaW 分析中考虑并行区域。 | | `-copy-before-write` | Skip the analysis. Make a buffer copy on every write. | 跳过分析,对每次写入都做一次缓冲拷贝。 | | `-dialect-filter` | Restrict bufferization to ops from these dialects. | 将缓冲化限制为来自这些方言的 op。 | | `-dump-alias-sets` | Test only: Annotate tensor IR with alias sets | 仅测试用:用别名集(alias set)标注 tensor IR。 | | `-no-analysis-func-filter` | Skip analysis of functions with these symbol names. Set copyBeforeWrite to true when bufferizing them. | 跳过对这些符号名函数的分析;缓冲化它们时将 copyBeforeWrite 设为 true。 | | `-function-boundary-type-conversion` | Controls layout maps when bufferizing function signatures. | 控制缓冲化函数签名时的布局映射。 | | `-must-infer-memory-space` | The memory space of an memref types must always be inferred. If unset, a default memory space of 0 is used otherwise. | memref 类型的内存空间必须始终被推断;若未设置,则默认使用内存空间 0。 | | `-use-encoding-for-memory-space` | Use the Tensor encoding attribute for the memory space. Exclusive to the 'must-infer-memory-space' option | 使用 Tensor 的 encoding 属性作为内存空间;与 'must-infer-memory-space' 选项互斥。 | | `-test-analysis-only` | Test only: Only run inplaceability analysis and annotate IR | 仅测试用:只运行 in-placability 分析并标注 IR。 | | `-print-conflicts` | Test only: Annotate IR with RaW conflicts. Requires test-analysis-only. | 仅测试用:用 RaW 冲突标注 IR;需要 test-analysis-only。 | | `-unknown-type-conversion` | Controls layout maps for non-inferrable memref types. | 控制不可推断的 memref 类型的布局映射。 | | `-buffer-alignment` | Sets the alignment of newly allocated buffers. | 设置新分配缓冲的对齐方式。 | **Statistics / 统计:** | Statistic | EN description | 中文说明 | |---|---|---| | `num-buffer-alloc` | Number of buffer allocations | 缓冲分配的数量。 | | `num-tensor-in-place` | Number of in-place tensor OpOperands | 原地(in-place)tensor OpOperand 的数量。 | | `num-tensor-out-of-place` | Number of out-of-place tensor OpOperands | 非原地(out-of-place)tensor OpOperand 的数量。 | --- ### -optimize-allocation-liveness **EN:** This pass optimizes the liveness of temp allocations in the input function **中文:** 本 Pass 优化输入函数中临时分配(temp allocation)的活跃性(liveness)。 **EN:** This pass will find all operations that have a memory allocation effect. It will search for the corresponding deallocation and move it right after the last user of the allocation. This will optimize the liveness of the allocations. The pass is expected to run after the deallocation pipeline. **中文:** 本 Pass 会找出所有具有内存分配副作用(memory allocation effect)的操作。它会查找对应的释放操作(deallocation),并将其移动到该分配的最后一个使用点之后。这将优化这些分配的活跃性(liveness)。该 Pass 预期在释放流水线(deallocation pipeline)之后运行。 ### -ownership-based-buffer-deallocation **EN:** Adds all required dealloc operations for all allocations in the input program **中文:** 为输入程序中的所有分配添加所有必需的 dealloc(释放)操作。 **EN:** This pass implements an algorithm to automatically introduce all required deallocation operations for all buffers in the input program. This ensures that the resulting program does not have any memory leaks. The Buffer Deallocation pass operates on the level of operations implementing the FunctionOpInterface. Such operations can take MemRefs as arguments, but also return them. To ensure compatibility among all functions (including external ones), some rules have to be enforced. They are just assumed to hold for all external functions. Functions for which the definition is available ideally also already adhere to the ABI. Otherwise, all MemRef write operations in the input IR must dominate all MemRef read operations in the input IR. Then, the pass may modify the input IR by inserting bufferization.clone operations such that the output IR adheres to the function boundary ABI: **中文:** 本 Pass 实现了一个算法,自动为输入程序中的所有 buffer 引入所有必需的释放(deallocation)操作。这确保生成的程序不存在任何内存泄漏。Buffer Deallocation pass 在实现了 FunctionOpInterface 的操作层级上工作。这类操作可以把 MemRef 作为参数接收,也可以返回它们。为了确保在所有函数(包括外部函数)之间保持兼容,必须强制遵守一些规则。这些规则被假定对所有外部函数都成立。对于定义可见的函数,理想情况下它们已经符合 ABI(应用二进制接口)。否则,输入 IR 中所有的 MemRef 写操作必须在支配关系上支配(dominate)输入 IR 中的所有 MemRef 读操作。随后,该 Pass 可以通过插入 bufferization.clone 操作来修改输入 IR,使得输出 IR 遵守函数边界 ABI: **EN:** When a MemRef is passed as a function argument, ownership is never acquired. It is always the caller's responsibility to deallocate such MemRefs. **中文:** 当一个 MemRef 作为函数参数传入时,永远不会获取其所有权。释放此类 MemRef 始终由调用方(caller)负责。 **EN:** Returning a MemRef from a function always passes ownership to the caller, i.e., it is also the caller's responsibility to deallocate MemRefs returned from a called function. **中文:** 从一个函数返回一个 MemRef 总是把所有权传递给调用方,也就是说,由被调用函数返回的 MemRef 也应由调用方负责释放。 **EN:** A function must not return a MemRef with the same allocated base buffer as one of its arguments (in this case a copy has to be created). Note that in this context two subviews of the same buffer that don't overlap are also considered an alias. **中文:** 一个函数不得返回与其某个参数具有相同已分配底层 buffer(base buffer)的 MemRef(在这种情况下必须创建一份拷贝)。注意,在此上下文中,同一 buffer 上两个不重叠的子视图(subview)也被视为别名(alias)。 **EN:** It is recommended to bufferize all operations first such that no tensor values remain in the IR once this pass is applied. That way all allocated MemRefs will be properly deallocated without any additional manual work. **中文:** 建议先对所有操作执行 bufferization,使得在应用本 Pass 时 IR 中不再残留任何 tensor 值。这样所有已分配的 MemRef 都会被妥善释放,无需额外的人工工作。 **EN:** Otherwise, the pass that bufferizes the remaining tensors is responsible to add the corresponding deallocation operations. Note that this pass does not consider any values of tensor type and assumes that MemRef values defined by bufferization.to_buffer do not return ownership and do not have to be deallocated. **中文:** 否则,负责 bufferize 剩余 tensor 的 Pass 需要添加相应的释放操作。注意,本 Pass 不考虑任何 tensor 类型的值,并假定由 bufferization.to_buffer 定义的 MemRef 值不返回所有权、因此无需被释放。 **EN:** bufferization.to_tensor operations are handled similarly to bufferization.clone operations with the exception that the result value is not handled because it's a tensor (not a MemRef). **中文:** bufferization.to_tensor 操作的处理方式与 bufferization.clone 类似,区别在于其结果值不会被处理,因为它是一个 tensor(而非 MemRef)。 **Input / 输入:** ```mlir #map0 = affine_map<(d0) -> (d0)> module { func.func @condBranch(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) { cf.cond_br %arg0, ^bb1, ^bb2 ^bb1: cf.br ^bb3(%arg1 : memref<2xf32>) ^bb2: %0 = memref.alloc() : memref<2xf32> linalg.generic { indexing_maps = [#map0, #map0], iterator_types = ["parallel"]} outs(%arg1, %0 : memref<2xf32>, memref<2xf32>) { ^bb0(%gen1_arg0: f32, %gen1_arg1: f32): %tmp1 = exp %gen1_arg0 : f32 linalg.yield %tmp1 : f32 } cf.br ^bb3(%0 : memref<2xf32>) ^bb3(%1: memref<2xf32>): "memref.copy"(%1, %arg2) : (memref<2xf32>, memref<2xf32>) -> () return } } ``` **Output / 输出:** ```mlir #map = affine_map<(d0) -> (d0)> module { func.func @condBranch(%arg0: i1, %arg1: memref<2xf32>, %arg2: memref<2xf32>) { %false = arith.constant false %true = arith.constant true cf.cond_br %arg0, ^bb1, ^bb2 ^bb1: // pred: ^bb0 cf.br ^bb3(%arg1, %false : memref<2xf32>, i1) ^bb2: // pred: ^bb0 %alloc = memref.alloc() : memref<2xf32> linalg.generic { indexing_maps = [#map, #map], iterator_types = ["parallel"]} outs(%arg1, %alloc : memref<2xf32>, memref<2xf32>) ^bb0(%out: f32, %out_0: f32): %2 = math.exp %out : f32 linalg.yield %2, %out_0 : f32, f32 } cf.br ^bb3(%alloc, %true : memref<2xf32>, i1) ^bb3(%0: memref<2xf32>, %1: i1): // 2 preds: ^bb1, ^bb2 memref.copy %0, %arg2 : memref<2xf32> to memref<2xf32> %base_buffer, %offset, %sizes, %strides = memref.extract_strided_metadata %0 : memref<2xf32> -> memref, index, index, index bufferization.dealloc (%base_buffer : memref) if (%1) return } } ``` **EN:** The private-function-dynamic-ownership pass option allows the pass to add additional arguments to private functions to dynamically give ownership of MemRefs to callees. This can enable earlier deallocations and allows the pass to by-pass the function boundary ABI and thus potentially leading to fewer MemRef clones being inserted. For example, the private function **中文:** `private-function-dynamic-ownership` 这个 Pass 选项允许该 Pass 为私有函数添加额外参数,以动态地把 MemRef 的所有权交给被调用方(callee)。这可以启用更早的释放,并让该 Pass 绕过函数边界 ABI,从而可能减少插入的 MemRef clone 数量。例如,下面这个私有函数 ```mlir func.func private @passthrough(%memref: memref<2xi32>) -> memref<2xi32> { return %memref : memref<2xi32> } ``` **EN:** would be converted to **中文:** 会被转换为 ```mlir func.func private @passthrough(%memref: memref<2xi32>, %ownership: i1) -> (memref<2xi32>, i1) { return %memref, %ownership : memref<2xi32>, i1 } ``` **EN:** and thus allows the returned MemRef to alias with the MemRef passed as argument (which would otherwise be forbidden according to the function boundary ABI). **中文:** 从而允许返回的 MemRef 与作为参数传入的 MemRef 形成别名(alias)关系(否则根据函数边界 ABI,这是被禁止的)。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-private-function-dynamic-ownership` | Allows to add additional arguments to private functions to dynamically pass ownership of memrefs to callees. This can enable earlier deallocations. | 允许为私有函数添加额外参数,以动态地把 memref 的所有权传递给被调用方。这可以启用更早的释放(deallocation)。| ### -promote-buffers-to-stack **EN:** Promotes heap-based allocations to automatically managed stack-based allocations **中文:** 把基于堆(heap)的分配提升为自动管理的基于栈(stack)的分配。 **EN:** This pass implements a simple algorithm to convert heap-based memory allocations to stack-based ones. It uses a built-in heuristic to decide whether it makes sense to convert an allocation. Furthermore, dynamic shaped buffers that are limited by the rank of the tensor can be converted. They are only transformed if they are considered to be small. **中文:** 本 Pass 实现了一个简单算法,把基于堆的内存分配转换为基于栈的分配。它使用一个内置启发式(heuristic)来决定是否值得转换某个分配。此外,受 tensor rank 限制的动态形状 buffer 也可以被转换;只有当它们被认为足够小时才会被转换。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-max-alloc-size-in-bytes` | Maximal size in bytes to promote allocations to stack. | 提升到栈上的分配的最大字节数。| | `-max-rank-of-allocated-memref` | Maximal memref rank to promote dynamic buffers. | 提升动态 buffer 所允许的最大 memref rank(维数)。| ### -static-memory-planner-analysis **EN:** Transforms same-block alloc/dealloc pairs into static arena allocation with computed offsets **中文:** 把同一基本块中的 alloc/dealloc 对转换为带有计算偏移的静态 arena 分配。 **EN:** This pass identifies and transforms memref.alloc / memref.dealloc pairs in the same basic block into a single static arena allocation. **中文:** 本 Pass 识别并转换同一基本块(basic block)中的 memref.alloc / memref.dealloc 对,将其合并为单个静态 arena 分配。 **EN:** For each memref.alloc the pass checks a conservative eligibility envelope: **中文:** 对于每个 memref.alloc,该 Pass 会检查一个保守的资格条件范围(eligibility envelope): **EN:** Static memref shape. **中文:** 静态(static)的 memref 形状。 **EN:** The allocation lives directly in the function's entry block (allocations nested in a region are skipped for now). **中文:** 该分配直接位于函数的入口块(entry block)中(目前嵌套在 region 中的分配会被跳过)。 **EN:** Every memref.dealloc that may free the buffer is anchored in the entry block. Deallocs reached indirectly through arith.select , scf.if results, cf branches, or view ops are handled via the shared BufferViewFlowAnalysis ; a dealloc nested inside an entry-block op (e.g. an scf.if body) is accepted and bounds the lifetime conservatively. **中文:** 每一个可能释放该 buffer 的 memref.dealloc 都锚定在入口块中。通过 arith.select、scf.if 结果、cf 分支或 view 操作间接到达的 dealloc,会经由共享的 BufferViewFlowAnalysis 来处理;嵌套在某个入口块 op(例如 scf.if 的 body)内部的 dealloc 会被接受,并保守地界定其生命周期边界。 **EN:** Eligible allocations are packed into a single arena using a configurable planning algorithm (see the algorithm option). The arena is an i8 byte buffer ( memref ) that can hold allocations of different element types. Each original allocation is replaced with a memref.view operation that creates a typed view into the arena at the computed offset. **中文:** 符合条件的分配会由一个可配置的规划算法(planning algorithm,见 `algorithm` 选项)打包进单个 arena。该 arena 是一个 i8 字节 buffer(memref),可以容纳具有不同元素类型的分配。每个原始分配都会被替换为一个 memref.view 操作,它在计算出的偏移处创建指向 arena 的类型化视图(typed view)。 **EN:** Ineligible allocations are skipped and retain their original alloc/dealloc operations. Skip reasons are reported via op remarks. Aggregate counts are reported as pass statistics. **中文:** 不符合条件的分配会被跳过,并保留其原有的 alloc/dealloc 操作。跳过原因通过 op remark 报告;汇总计数作为 Pass 统计(statistics)上报。 **EN:** This pass is expected to run after the deallocation pipeline ( ownership-based-buffer-deallocation followed by bufferization-lower-deallocations ). **中文:** 本 Pass 预期在释放流水线之后运行(即先 `ownership-based-buffer-deallocation`,再 `bufferization-lower-deallocations`)。 **Example transformation / 变换示例:** ```mlir // Before: func.func @example() { %0 = memref.alloc() : memref<1024xf32> "some.use"(%0) : (memref<1024xf32>) -> () memref.dealloc %0 : memref<1024xf32> return } // After: func.func @example() { %arena = memref.alloc() {alignment = 1 : i64} : memref<4096xi8> %c0 = arith.constant 0 : index %0 = memref.view %arena[%c0][] : memref<4096xi8> to memref<1024xf32> "some.use"(%0) : (memref<1024xf32>) -> () return } ``` **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-arena-mode` | Arena allocation mode: 'allocate' creates arena via AllocOp, 'arg' extracts arena from function arguments | Arena 分配模式:'allocate' 通过 AllocOp 创建 arena,'arg' 从函数参数中提取 arena。| | `-algorithm` | Memory planning algorithm to use. | 要使用的内存规划算法(memory planning algorithm)。| **Statistics / 统计:** | Statistic | EN description | 中文说明 | |---|---|---| | `num-eligible` | Number of alloc/dealloc pairs eligible for static planning | 符合静态规划(static planning)条件的 alloc/dealloc 对数量。| | `num-skipped-dynamic` | Number of allocations skipped: dynamic shape | 被跳过的分配数:动态形状(dynamic shape)。| | `num-skipped-nested` | Number of allocations skipped: nested in loop or conditional | 被跳过的分配数:嵌套在循环或条件中。| | `num-skipped-no-dealloc` | Number of allocations skipped: no unique same-block dealloc | 被跳过的分配数:没有唯一的同块(same-block)dealloc。| | `num-skipped-escaping` | Number of allocations skipped: cross-block alias or escaping use | 被跳过的分配数:跨块别名或逃逸使用(escaping use)。| --- ## Conversion Passes(转换 Pass) ### -acc-to-llvm **EN:** Lower OpenACC operations to LLVM dialect. **中文:** 将 OpenACC 操作降低到 LLVM 方言。 ### -arm-neon-2d-to-intr **EN:** Convert Arm NEON structured ops to intrinsics **中文:** 将 Arm NEON 结构化操作转换为内建函数(intrinsics)。 **EN:** Creates a pass to lower Arm NEON 2D ops to intrinsics, i.e. equivalent ops operating on flattened 1D vectors and mapping more directly to the corresponding Arm NEON instruction. **中文:** 创建一个 Pass,将 Arm NEON 二维操作降低为内建函数(intrinsics),即在展平后的一维向量上操作的等效 op,更直接地映射到对应的 Arm NEON 指令。 ### -convert-affine-for-to-gpu **EN:** Convert top-level AffineFor Ops to GPU kernels **中文:** 将顶层 AffineFor Op 转换为 GPU kernel。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-gpu-block-dims` | Number of GPU block dimensions for mapping | 用于映射的 GPU block 维度数 | | `-gpu-thread-dims` | Number of GPU thread dimensions for mapping | 用于映射的 GPU thread 维度数 | ### -convert-amdgpu-to-rocdl **EN:** Convert AMDGPU dialect to ROCDL dialect **中文:** 将 AMDGPU 方言转换为 ROCDL 方言。 **EN:** This pass converts supported AMDGPU ops to ROCDL dialect intrinsics. **中文:** 此 Pass 将受支持的 AMDGPU op 转换为 ROCDL 方言的内建函数(intrinsics)。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-chipset` | Chipset that these operations will run on | 这些操作将运行的芯片组 | ### -convert-arith-to-amdgpu **EN:** Convert Arith operations to AMDGPU-specific implementations **中文:** 将 Arith 操作转换为 AMDGPU 专用实现。 **EN:** Convert arith operations (currently extf and truncf on 8-bit floats) to operations in the amdgpu dialect. This pass is done in two steps in order to avoid running a notional arith-to-rocdl and arith-to-llvm simultaniously. **中文:** 将 arith 操作(目前为 8 位浮点数的 extf 和 truncf)转换为 amdgpu 方言中的操作。此 Pass 分两步执行,以避免同时运行假设性的 arith-to-rocdl 和 arith-to-llvm。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-chipset` | Chipset that these operations will run on | 这些操作将运行的芯片组 | | `-saturate-fp8-truncf` | Use saturating truncation for 8-bit float types | 对 8 位浮点类型使用饱和截断(saturating truncation) | | `-allow-packed-f16-round-to-zero` | Whether we should allow f32->f16 packed round-to-zero conversion | 是否允许 f32→f16 packed round-to-zero 转换 | ### -convert-arith-to-apfloat **EN:** Convert Arith ops to APFloat runtime library calls **中文:** 将 Arith op 转换为 APFloat 运行时库调用。 **EN:** This pass converts supported Arith ops to APFloat-based runtime library calls (APFloatWrappers.cpp). APFloat is a software implementation of floating-point arithmetic operations. **中文:** 此 Pass 将受支持的 Arith op 转换为基于 APFloat 的运行时库调用(APFloatWrappers.cpp)。APFloat 是浮点算术运算的软件实现。 ### -convert-arith-to-arm-sme **EN:** Convert Arith dialect to ArmSME dialect **中文:** 将 Arith 方言转换为 ArmSME 方言。 ### -convert-arith-to-emitc **EN:** Convert Arith dialect to EmitC dialect **中文:** 将 Arith 方言转换为 EmitC 方言。 ### -convert-arith-to-llvm **EN:** Convert Arith dialect to LLVM dialect **中文:** 将 Arith 方言转换为 LLVM 方言。 **EN:** This pass converts supported Arith ops to LLVM dialect instructions. **中文:** 此 Pass 将受支持的 Arith op 转换为 LLVM 方言指令。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-index-bitwidth` | Bitwidth of the index type, 0 to use size of machine word | index 类型的位宽,0 表示使用机器字大小 | ### -convert-arith-to-spirv **EN:** Convert Arith dialect to SPIR-V dialect **中文:** 将 Arith 方言转换为 SPIR-V 方言。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-emulate-lt-32-bit-scalar-types` | Emulate narrower scalar types with 32-bit ones if not supported by the target | 若目标不支持更窄的标量类型,则用 32 位类型进行模拟(emulation) | | `-emulate-unsupported-float-types` | Emulate unsupported float types by representing them with integer types of same bit width | 用相同位宽的整数类型来表示不支持的浮点类型以进行模拟 | ### -convert-arm-sme-to-llvm **EN:** Lower the operations from the ArmSME dialect into the LLVM dialect **中文:** 将 ArmSME 方言中的操作降低到 LLVM 方言。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-dump-tile-live-ranges` | Dump the live ranges of SME tiles (for debugging) | 转储(dump)SME tile 的活跃区间(live range),用于调试 | ### -convert-arm-sme-to-scf **EN:** Lower the operations from the ArmSME dialect into the SCF dialect **中文:** 将 ArmSME 方言中的操作降低到 SCF 方言。 ### -convert-async-to-llvm **EN:** Convert the operations from the async dialect into the LLVM dialect **中文:** 将 async 方言中的操作转换为 LLVM 方言。 **EN:** Convert async.execute operations to LLVM coroutines and use async runtime API to execute them. **中文:** 将 async.execute 操作转换为 LLVM coroutine,并使用 async 运行时 API 执行它们。 ### -convert-bufferization-to-memref **EN:** Convert operations from the Bufferization dialect to the MemRef dialect **中文:** 将 Bufferization 方言中的操作转换为 MemRef 方言。 **EN:** This pass converts bufferization operations into memref operations. In the current state, this pass only transforms a bufferization.clone operation into memref.alloc and memref.copy operations and bufferization.dealloc operations (the same way as the -bufferizationlower-deallocations pass). The conversion of clone operations is needed, since some clone operations could remain after applying several transformation processes. Currently, only canonicalize transforms clone operations or even eliminates them. This can lead to errors if any clone op survived after all conversion passes (starting from the bufferization dialect) are performed. See: https://llvm.discourse.group/t/bufferization-error-related-to-memref-clone/4665 To avoid these errors, this pass can be performed as a last clean-up pass to transform remaining operations and to proceed in other dialects (memref e.g.). Note that this pass only transforms the operation without any further analyses. This pass does not consider any memory analysis or optimization and hence does not resolve any memory leaks. **中文:** 此 Pass 将 bufferization 操作转换为 memref 操作。目前,此 Pass 仅将 bufferization.clone 操作转换为 memref.alloc 和 memref.copy 操作,以及 bufferization.dealloc 操作(方式与 -bufferizationlower-deallocations pass 相同)。需要转换 clone 操作,因为在应用多个变换过程后仍可能残留一些 clone 操作。目前只有 canonicalize 会变换或消除 clone 操作。如果在执行所有转换 pass(从 bufferization 方言开始)之后仍有 clone op 存活,可能导致错误。参见:https://llvm.discourse.group/t/bufferization-error-related-to-memref-clone/4665 。为避免这些错误,此 Pass 可作为最后的清理 pass 执行,以变换剩余操作并继续处理其他方言(如 memref)。注意,此 Pass 仅转换操作而不进行任何进一步分析。此 Pass 不考虑任何内存分析或优化,因此不会解决任何内存泄漏。 --- ### -convert-cf-to-llvm **EN:** Convert ControlFlow operations to the LLVM dialect **中文:** 将 ControlFlow 操作转换为 LLVM 方言。 **EN:** Convert ControlFlow operations into LLVM IR dialect operations. If other operations are present and their results are required by the LLVM IR dialect operations, the pass will fail. Any LLVM IR operations or types already present in the IR will be kept as is. **中文:** 将 ControlFlow 操作转换为 LLVM IR 方言的 op。若存在其他 op、且其结果被 LLVM IR 方言的 op 所依赖,该 Pass 将会失败(fail)。IR 中已存在的任何 LLVM IR op 或类型都会原样保留。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-index-bitwidth` | Bitwidth of the index type, 0 to use size of machine word | index 类型的位宽,为 0 时使用机器字大小(machine word) | ### -convert-cf-to-spirv **EN:** Convert ControlFlow dialect to SPIR-V dialect **中文:** 将 ControlFlow 方言转换为 SPIR-V 方言。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-emulate-lt-32-bit-scalar-types` | Emulate narrower scalar types with 32-bit ones if not supported by the target | 若目标不支持更窄的标量类型,则用 32 位类型来模拟它们 | | `-emulate-unsupported-float-types` | Emulate unsupported float types by representing them with integer types of same bit width | 通过用相同位宽的整数类型来表示,从而模拟不受支持的浮点类型 | ### -convert-complex-to-libm **EN:** Convert Complex dialect to libm calls **中文:** 将 Complex(复数)方言转换为 libm 调用。 **EN:** This pass converts supported Complex ops to libm calls. **中文:** 该 Pass 将受支持的 Complex op 转换为 libm 调用。 ### -convert-complex-to-llvm **EN:** Convert Complex dialect to LLVM dialect **中文:** 将 Complex(复数)方言转换为 LLVM 方言。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-complex-range` | Control the intermediate calculation of complex number division | 控制复数除法的中间计算 | ### -convert-complex-to-rocdl-library-calls **EN:** Convert Complex dialect to ROCDL library calls **中文:** 将 Complex(复数)方言转换为 ROCDL 库调用。 **EN:** This pass converts supported Complex ops to calls to the AMD device library. **中文:** 该 Pass 将受支持的 Complex op 转换为对 AMD 设备库的调用。 ### -convert-complex-to-spirv **EN:** Convert Complex dialect to SPIRV dialect **中文:** 将 Complex(复数)方言转换为 SPIRV 方言。 ### -convert-complex-to-standard **EN:** Convert Complex dialect to standard dialect **中文:** 将 Complex(复数)方言转换为 standard(标准)方言。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-complex-range` | Control the intermediate calculation of complex number division | 控制复数除法的中间计算 | ### -convert-func-to-emitc **EN:** Convert Func dialect to EmitC dialect **中文:** 将 Func 方言转换为 EmitC 方言。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-lower-to-cpp` | Target C++ (true) instead of C (false) | 目标语言为 C++(true)而非 C(false) | ### -convert-func-to-llvm **EN:** Convert from the Func dialect to the LLVM dialect **中文:** 从 Func 方言转换为 LLVM 方言。 **EN:** Convert Func dialect operations into the LLVM IR dialect operations. **中文:** 将 Func 方言的 op 转换为 LLVM IR 方言的 op。 **Input invariant / 输入不变量:** **EN:** - no tensor types; - all vector are one-dimensional; - all blocks are reachable by following the successors of the first basic block; If other operations are present and their results are required by the LLVM IR dialect operations, the pass will fail. Any LLVM IR operations or types already present in the IR will be kept as is. An LLVM datalayout string can be attached as an attribute to the module on which the pass anchors. Such an attribute is attached by calling the set-module-datalayout pass. If present, an llvm::DataLayout object is created from this attribute and used in the conversion to LLVM. **中文:** - 不含 tensor(张量)类型; - 所有 vector(向量)均为一维; - 沿第一个基本块的 successors(后继块)可达所有 block(基本块)。 若存在其他 op、且其结果被 LLVM IR 方言的 op 所依赖,该 Pass 将会失败。IR 中已存在的任何 LLVM IR op 或类型都会原样保留。可以将一个 LLVM datalayout 字符串作为属性附加到该 Pass 所锚定(anchor)的 module(模块)上;这样的属性通过调用 set-module-datalayout pass 来附加。若存在,则从该属性创建一个 llvm::DataLayout 对象,并用于向 LLVM 的转换过程。 **Output IR / 输出 IR:** **EN:** Functions converted to LLVM IR. Function arguments types are converted one-to-one. Function results are converted one-to-one and, in case more than 1 value is returned, packed into an LLVM IR struct type. Function calls and returns are updated accordingly. Block argument types are updated to use LLVM IR types. **中文:** 函数被转换为 LLVM IR。函数参数类型按一对一(one-to-one)转换;函数结果也按一对一转换,若返回多于一个值,则打包为一个 LLVM IR struct(结构体)类型。函数调用与返回相应更新。block 参数的类型更新为使用 LLVM IR 类型。 **Function discardable attributes / 函数的可丢弃属性:** **EN:** Discardable attributes on func.func are lowered as follows. - LLVM llvm.func properties. Each inherent attribute defined on llvm.func (ODS properties such as target_cpu , linkage , vscale_range , passthrough , and so on) must be attached to func.func using the llvm. prefix (for example llvm.target_cpu , llvm.vscale_range ). The pass strips that prefix, validates the attribute value the same way as for llvm.func , and fills the corresponding fields on the generated llvm.func . Values that fail validation make conversion fail. - Unprefixed legacy names. A discardable attribute whose name equals the bare ODS property name (without llvm. ) is not forwarded: it is dropped. Only the explicit llvm.* spelling is lowered into llvm.func properties so that front ends cannot accidentally rely on ambiguous short names. - Opaque pass-through. Any other discardable attribute is copied onto the llvm.func unchanged, so arbitrary metadata can survive the conversion. That includes names that start with llvm. but are not inherent llvm.func properties (for example dialect-specific markers): they are not interpreted as properties and are forwarded as discardable attributes on the result. - func.varargs . This attribute is interpreted when converting the function type (variadic LLVM signature). It is not an LLVM IR dialect property and is handled separately from the llvm.* property mapping above. - llvm.readnone . If present, the pass also sets memory_effects on the llvm.func to read-none semantics, in addition to any other attribute handling. **中文:** func.func 上的可丢弃属性(discardable attributes)按如下方式被 lower。 - LLVM `llvm.func` 属性。定义在 `llvm.func` 上的每个固有属性(inherent attribute,如 target_cpu、linkage、vscale_range、passthrough 等 ODS property)必须使用 llvm. 前缀附加到 func.func 上(例如 llvm.target_cpu、llvm.vscale_range)。该 Pass 会剥掉该前缀,以与 `llvm.func` 相同的方式校验属性值,并填充所生成 `llvm.func` 的对应字段。校验失败的值会使转换失败。 - 无前缀的旧式名称。名称等于不带 llvm. 的裸 ODS property 名的可丢弃属性不会被转发:它会被丢弃(drop)。只有显式的 llvm.* 写法才会被 lower 为 `llvm.func` 的 property,以免前端意外依赖含义含糊的短名称。 - 不透明透传(opaque pass-through)。其他任何可丢弃属性都会原样复制到 `llvm.func` 上,因此任意元数据都能存活于转换之后。这包括以 llvm. 开头但并非 `llvm.func` 固有 property 的名称(例如方言特定的标记):它们不会被解释为 property,而是作为结果上的可丢弃属性被转发。 - func.varargs。该属性在转换函数类型(可变参数的 LLVM 签名)时会被解释。它不是 LLVM IR 方言的 property,独立于上述 llvm.* property 映射处理。 - llvm.readnone。若存在,除其他属性处理外,该 Pass 还会将 `llvm.func` 的 memory_effects 设置为 read-none 语义。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-use-bare-ptr-memref-call-conv` | Replace FuncOp's MemRef arguments with bare pointers to the MemRef element types | 用指向 MemRef 元素类型的裸指针(bare pointer)替换 FuncOp 的 MemRef 参数 | | `-index-bitwidth` | Bitwidth of the index type, 0 to use size of machine word | index 类型的位宽,为 0 时使用机器字大小 | ### -convert-func-to-spirv **EN:** Convert Func dialect to SPIR-V dialect **中文:** 将 Func 方言转换为 SPIR-V 方言。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-emulate-lt-32-bit-scalar-types` | Emulate narrower scalar types with 32-bit ones if not supported by the target | 若目标不支持更窄的标量类型,则用 32 位类型来模拟它们 | | `-emulate-unsupported-float-types` | Emulate unsupported float types by representing them with integer types of same bit width | 通过用相同位宽的整数类型来表示,从而模拟不受支持的浮点类型 | ### -convert-gpu-to-llvm-spv **EN:** Generate LLVM operations to be ingested by a SPIR-V backend for gpu operations **中文:** 为 GPU 操作生成可被 SPIR-V 后端接收(ingest)的 LLVM op。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-use-64bit-index` | Use 64-bit integers to convert index types | 使用 64 位整数来转换 index 类型 | ### -convert-gpu-to-nvvm **EN:** Generate NVVM operations for gpu operations **中文:** 为 GPU 操作生成 NVVM op。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-index-bitwidth` | Bitwidth of the index type, 0 to use size of machine word | index 类型的位宽,为 0 时使用机器字大小 | | `-has-redux` | Target gpu supports redux | 目标 GPU 支持 redux(规约)操作 | | `-use-bare-ptr-memref-call-conv` | Replace memref arguments in GPU functions with bare pointers. All memrefs must have static shape. | 用裸指针替换 GPU 函数中的 memref 参数。所有 memref 必须具有静态形状(static shape)。 | | `-allow-pattern-rollback` | Experimental performance flag to disallow pattern rollback | 实验性性能标志,用于禁止 pattern rollback(模式回滚) | | `-allowed-dialects` | Run conversion patterns of only the specified dialects | 仅运行指定方言的转换 pattern(模式) | ### -convert-gpu-to-rocdl **EN:** Generate ROCDL operations for gpu operations **中文:** 为 GPU 操作生成 ROCDL op。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-chipset` | Chipset that these operations will run on | 这些 op 将运行于其上的芯片组(chipset) | | `-index-bitwidth` | Bitwidth of the index type, 0 to use size of machine word | index 类型的位宽,为 0 时使用机器字大小 | | `-use-bare-ptr-memref-call-conv` | Replace memref arguments in GPU functions with bare pointers. All memrefs must have static shape | 用裸指针替换 GPU 函数中的 memref 参数。所有 memref 必须具有静态形状 | | `-runtime` | Runtime code will be run on (default is Unknown, can also use HIP or OpenCL) | 运行时代码将运行于其上(默认为 Unknown,也可使用 HIP 或 OpenCL) | | `-allowed-dialects` | Run conversion patterns of only the specified dialects | 仅运行指定方言的转换 pattern(模式) | ### -convert-gpu-to-spirv **EN:** Convert GPU dialect to SPIR-V dialect **中文:** 将 GPU 方言转换为 SPIR-V 方言。 **EN:** This pass converts supported GPU device ops to SPIR-V ops. It does not handle GPU host ops. **中文:** 该 Pass 将受支持的 GPU 设备(device)op 转换为 SPIR-V op。它不处理 GPU 主机(host)op。 **EN:** A gpu.func op can have parameters to pass in resources. But in SPIR-V entry functions cannot take parameters; they use descriptors to access resources. By default, parameters to a gpu.func op will be converted to global variables. These global variables will be assigned sequential binding numbers following their order in the original gpu.func op, starting from 0, in set 0. One can attach spirv.interface_var_abi to those parameters to control the set and binding if wanted. **中文:** `gpu.func` op 可以有参数用于传入资源(resources)。但在 SPIR-V 中,入口函数(entry functions)不能接受参数;它们使用 descriptor(描述符)来访问资源。默认情况下,`gpu.func` op 的参数会被转换为全局变量(global variables)。这些全局变量将按照其在原始 `gpu.func` op 中的顺序、从 0 开始被分配连续的 binding number(绑定号),位于 set 0。如需控制 set 与 binding,可以向这些参数附加 spirv.interface_var_abi。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-use-64bit-index` | Use 64-bit integers to convert index types | 使用 64 位整数来转换 index 类型 | --- ### -convert-index-to-llvm **EN:** Lower the index dialect to the llvm dialect. **中文:** 将 index 方言降级到 llvm 方言。 **EN:** This pass lowers Index dialect operations to LLVM dialect operations. Operation conversions are 1-to-1 except for the exotic divides: ceildivs, ceildivu, and floordivs, which expand to series of LLVM operations. Importantly, the index bitwidth should be correctly set to the target pointer width via index-bitwidth. **中文:** 此 Pass 将 Index 方言的操作降级为 LLVM 方言的操作。操作转换是一一对应的,但特殊的除法运算除外:ceildivs、ceildivu 和 floordivs 会被展开为一系列 LLVM 操作。重要的是,index 的位宽应通过 index-bitwidth 正确设置为目标的指针宽度(pointer width)。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-index-bitwidth` | Bitwidth of the index type, 0 to use size of machine word | index 类型的位宽,设为 0 表示使用机器字长(machine word)的大小 | ### -convert-index-to-spirv **EN:** Lower the index dialect to the spirv dialect. **中文:** 将 index 方言降级到 spirv 方言。 **EN:** This pass lowers Index dialect operations to SPIR-V dialect operations. Operation conversions are 1-to-1 except for the exotic divides: ceildivs, ceildivu, and floordivs. The index bitwidth will be 32 or 64 as specified by use-64bit-index. **中文:** 此 Pass 将 Index 方言的操作降级为 SPIR-V 方言的操作。操作转换是一一对应的,但特殊的除法运算除外:ceildivs、ceildivu 和 floordivs。index 的位宽将是 32 或 64,由 use-64bit-index 指定。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-use-64bit-index` | Use 64-bit integers to convert index types | 使用 64 位整数来转换 index 类型 | ### -convert-linalg-to-std **EN:** Convert the operations from the linalg dialect into the Standard dialect **中文:** 将 linalg 方言中的操作转换为 Standard(标准)方言。 ### -convert-math-to-apfloat **EN:** Convert Math ops to APFloat runtime library calls **中文:** 将 Math 操作转换为 APFloat 运行时库调用。 **EN:** This pass converts supported Math ops to APFloat-based runtime library calls (APFloatWrappers.cpp). APFloat is a software implementation of floating-point mathmetic operations. **中文:** 此 Pass 将受支持的 Math 操作转换为基于 APFloat 的运行时库调用(见 APFloatWrappers.cpp)。APFloat 是浮点算术运算的软件实现。 ### -convert-math-to-emitc **EN:** Convert some Math operations to EmitC call_opaque operations **中文:** 将部分 Math 操作转换为 EmitC 的 call_opaque 操作。 **EN:** This pass converts supported Math ops to call_opaque ops targeting libc/libm functions. Unlike convert-math-to-funcs pass, converting to call_opaque ops allows to overload the same function with different argument types. **中文:** 此 Pass 将受支持的 Math 操作转换为指向 libc/libm 函数的 call_opaque 操作。与 convert-math-to-funcs Pass 不同,转换为 call_opaque 操作允许用不同的参数类型对同一函数进行重载(overload)。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-language-target` | Select the language standard target for callees (c99 or cpp11). | 选择被调用函数(callee)的语言标准目标(c99 或 cpp11)。 | ### -convert-math-to-funcs **EN:** Convert Math operations to calls of outlined implementations. **中文:** 将 Math 操作转换为对外部化(outlined)实现的调用。 **EN:** This pass converts supported Math ops to calls of compiler generated functions implementing these operations in software. The LLVM dialect is used for LinkonceODR linkage of the generated functions. **中文:** 此 Pass 将受支持的 Math 操作转换为编译器生成的函数的调用,这些函数在软件中实现相应操作。LLVM 方言用于对生成的函数进行 LinkonceODR 链接(linkage)。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-min-width-of-fpowi-exponent` | Convert FPowI only if the width of its exponent's integer type is greater than or equal to this value | 仅当 FPowI 的指数(exponent)的整数类型宽度大于或等于该值时,才转换 FPowI | | `-convert-ctlz` | Convert math.ctlz to a software implementation. Enable for targets that do not natively support ctlz. | 将 math.ctlz 转换为软件实现。针对不原生支持 ctlz 的目标启用此项。 | ### -convert-math-to-libm **EN:** Convert Math dialect to libm calls **中文:** 将 Math 方言转换为 libm 调用。 **EN:** This pass converts supported Math ops to libm calls. **中文:** 此 Pass 将受支持的 Math 操作转换为 libm 调用。 ### -convert-math-to-llvm **EN:** Convert Math dialect to LLVM dialect **中文:** 将 Math 方言转换为 LLVM 方言。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-approximate-log1p` | Enable approximation of Log1p. | 启用对 Log1p 的近似计算。 | ### -convert-math-to-nvvm **EN:** Convert Math dialect to CUDA libdevice calls **中文:** 将 Math 方言转换为 CUDA libdevice 调用。 **EN:** This pass converts supported Math ops to CUDA libdevice calls. **中文:** 此 Pass 将受支持的 Math 操作转换为 CUDA libdevice 调用。 ### -convert-math-to-rocdl **EN:** Convert Math dialect to ROCDL library calls **中文:** 将 Math 方言转换为 ROCDL 库调用。 **EN:** This pass converts supported Math ops to ROCDL library calls. The chipset option specifies the target AMDGPU architecture. If the chipset is empty, none of the chipset-dependent patterns are added, and the pass will not attempt to parse the chipset. **中文:** 此 Pass 将受支持的 Math 操作转换为 ROCDL 库调用。chipset(芯片组)选项指定目标的 AMDGPU 架构。如果 chipset 为空,则不会添加任何依赖于 chipset 的模式(patterns),且该 Pass 不会尝试解析 chipset。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-chipset` | Chipset that these operations will run on | 这些操作将运行于其上的芯片组(chipset) | ### -convert-math-to-spirv **EN:** Convert Math dialect to SPIR-V dialect **中文:** 将 Math 方言转换为 SPIR-V 方言。 ### -convert-math-to-xevm **EN:** Convert (fast) math operations to native XeVM/SPIRV equivalents **中文:** 将(快速)math 操作转换为原生的 XeVM/SPIRV 等价实现。 **EN:** This pass converts supported math ops marked with the afn fastmath flag to function calls for OpenCL native_ math intrinsics: These intrinsics are typically mapped directly to native device instructions, often resulting in better performance. However, the precision/error of these intrinsics are implementation-defined, and thus math ops are only converted when they have the afn fastmath flag enabled. However, if the convertToOCL flag is set then all supported math ops would be lowered to OpenCL math intrinsics. **中文:** 此 Pass 将标记了 afn fastmath 标志的受支持 math 操作转换为针对 OpenCL native_ 数学内置函数(intrinsics)的函数调用:这些内置函数通常直接映射到设备的原生指令,往往能带来更好的性能。然而,这些内置函数的精度/误差是实现定义的(implementation-defined),因此只有启用了 afn fastmath 标志的 math 操作才会被转换。此外,如果设置了 convertToOCL 标志,则所有受支持的 math 操作都会被降级为 OpenCL 数学内置函数。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-convert-arith` | Convert supported Arith ops (e.g. arith.divf) as well. | 同时也转换受支持的 Arith 操作(例如 arith.divf)。 | | `-convert-to-ocl` | Convert supported Math ops to OCL intrinsics. | 将受支持的 Math 操作转换为 OCL 内置函数(intrinsics)。 | ### -convert-memref-to-emitc **EN:** Convert MemRef dialect to EmitC dialect **中文:** 将 MemRef 方言转换为 EmitC 方言。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-lower-to-cpp` | Target C++ (true) instead of C (false) | 目标是 C++(true)而非 C(false) | ### -convert-memref-to-spirv **EN:** Convert MemRef dialect to SPIR-V dialect **中文:** 将 MemRef 方言转换为 SPIR-V 方言。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-bool-num-bits` | The number of bits to store a boolean value | 存储布尔值所使用的位数 | | `-use-64bit-index` | Use 64-bit integers to convert index types | 使用 64 位整数来转换 index 类型 | --- ### -convert-nvgpu-to-nvvm **EN:** Convert NVGPU dialect to NVVM dialect This pass converts supported NVGPU ops to NVVM dialect intrinsics. **中文:** 将 NVGPU 方言(dialect)转换为 NVVM 方言。该 Pass 把受支持的 NVGPU op(算子)转换为 NVVM 方言的内建函数(intrinsics)。 ### -convert-nvvm-to-llvm **EN:** Convert NVVM to PTX with Inline Assembly in LLVM dialect This pass generates PTX instructions using inline assembly for NVVM operations implements BasicPtxBuilderInterface . **中文:** 在 LLVM 方言中以内联汇编(inline assembly)方式将 NVVM 转换为 PTX。该 Pass 为实现了 `BasicPtxBuilderInterface` 的 NVVM op 使用内联汇编生成 PTX 指令。 ### -convert-openacc-to-scf **EN:** Convert the OpenACC ops to OpenACC with SCF dialect **中文:** 将 OpenACC op 转换为结合 SCF 方言的 OpenACC。 ### -convert-openmp-to-llvm **EN:** Convert the OpenMP ops to OpenMP ops with LLVM dialect **中文:** 将 OpenMP op 转换为结合 LLVM 方言的 OpenMP op。 ### -convert-parallel-loops-to-gpu **EN:** Convert mapped scf.parallel ops to gpu launch operations Creates a pass that converts scf.parallel operations into a gpu.launch operation. The mapping of loop dimensions to launch dimensions is derived from mapping attributes. See ParallelToGpuLaunchLowering::matchAndRewrite for a description of the used attributes. **中文:** 将带映射的 `scf.parallel` op 转换为 GPU 启动(launch)操作。该 Pass 把 `scf.parallel` 操作转换为 `gpu.launch` 操作;循环维度到启动维度的映射由 mapping attribute(映射属性)推导得出。所用属性的说明参见 `ParallelToGpuLaunchLowering::matchAndRewrite`。 ### -convert-pdl-to-pdl-interp **EN:** Convert PDL ops to PDL interpreter ops **中文:** 将 PDL op 转换为 PDL 解释器(interpreter)op。 ### -convert-scf-to-cf **EN:** Convert SCF dialect to ControlFlow dialect, replacing structured control flow with a CFG **中文:** 将 SCF 方言转换为 ControlFlow(控制流)方言,用 CFG(control-flow graph,控制流图)取代结构化控制流。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-allow-pattern-rollback` | Experimental performance flag to disallow pattern rollback | 实验性性能标志,用于禁止模式回滚(pattern rollback) | ### -convert-scf-to-emitc **EN:** Convert SCF dialect to EmitC dialect, maintaining structured control flow **中文:** 将 SCF 方言转换为 EmitC 方言,并保持结构化控制流。 ### -convert-scf-to-openmp **EN:** Convert SCF parallel loop to OpenMP parallel + workshare constructs. **中文:** 将 SCF 并行循环转换为 OpenMP parallel + workshare 构造(constructs)。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-num-threads` | Number of threads to use | 要使用的线程数 | ### -convert-scf-to-spirv **EN:** Convert SCF dialect to SPIR-V dialect. Converts SCF ops into SPIR-V structured control flow ops. SPIR-V structured control flow ops do not support yielding values. So for SCF ops yielding values, SPIR-V variables are created for holding the values and load/store operations are emitted for updating them. **中文:** 将 SCF 方言转换为 SPIR-V 方言。该 Pass 把 SCF op 转换为 SPIR-V 结构化控制流 op。SPIR-V 的结构化控制流 op 不支持 yield(产出)值,因此对于会 yield 值的 SCF op,会创建用于保存这些值的 SPIR-V 变量,并生成 load/store(加载/存储)操作来更新它们。 ### -convert-shape-constraints **EN:** Convert shape constraint operations to the standard dialect This pass eliminates shape constraints from the program, converting them to eager (side-effecting) error handling code. This pass is separate from the regular convert-shape-to-standard, despite converting between the same dialects, because converting shape constraints can happen at a different part of the program than general shape computation lowering. **中文:** 将 shape constraint(形状约束)操作转换为标准方言。该 Pass 从程序中消除形状约束,把它们转换为 eager(急切的、带副作用的 side-effecting)错误处理代码。尽管转换的是相同的两个方言,但该 Pass 与常规的 `convert-shape-to-standard` 相互独立,因为形状约束的转换可能发生在程序中与一般 shape computation(形状计算)lowering(降级/降低)不同的位置。 ### -convert-shape-to-std **EN:** Convert operations from the shape dialect into the standard dialect **中文:** 将 shape(形状)方言中的操作转换为标准(standard)方言。 ### -convert-shard-to-mpi **EN:** Convert Shard dialect to MPI dialect. This pass lowers communication operations from the Shard dialect to the MPI dialect. If the module contains the DLTI attribute "MPI:comm_world-rank", its integer value is used as the rank instead of calling MPI_Comm_rank. This enables optimizations such as constant shape propagation and fusion, since shard and partition sizes can be determined from the rank. For some operations the conversion may require intermediate memref allocations. For compatibility with the buffer deallocation pipeline, these allocations are only deallocated when the lowered operations return buffers. When the operation was defined in tensor-land, no explicit deallocation is performed. This means that the deallocation must be handled by different means, e.g. by the deallocation pipeline. **中文:** 将 Shard(分片)方言转换为 MPI 方言。该 Pass 把 Shard 方言中的通信操作降级(lowering)为 MPI 方言。如果模块包含 DLTI attribute `"MPI:comm_world-rank"`,则其整数值会被直接用作 rank(进程排名),而不再调用 `MPI_Comm_rank`。由于 shard 与 partition 的尺寸可以从 rank 推得,这使常量形状传播、融合等优化成为可能。某些操作的转换可能需要中间的 memref 分配;为了与 buffer deallocation pipeline(缓冲区释放流水线)兼容,这些分配只有在被降级后的操作返回 buffer(缓冲区)时才会被释放。如果原操作定义在 tensor-land(张量域),则不执行显式释放——这意味着必须通过其他手段处理释放,例如由释放流水线完成。 ### -convert-spirv-to-llvm **EN:** Convert SPIR-V dialect to LLVM dialect See https://mlir.llvm.org/docs/SPIRVToLLVMDialectConversion/ for more details. **中文:** 将 SPIR-V 方言转换为 LLVM 方言。更多细节参见 https://mlir.llvm.org/docs/SPIRVToLLVMDialectConversion/ 。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-client-api` | Derive StorageClass to address space mapping from the client API | 从客户端 API(client API)推导 StorageClass 到地址空间(address space)的映射 | --- ### -convert-tensor-to-linalg **EN:** Convert some Tensor dialect ops to Linalg dialect **中文:** 将部分 Tensor(张量)方言的 op 转换为 Linalg 方言。 ### -convert-tensor-to-spirv **EN:** Convert Tensor dialect to SPIR-V dialect **中文:** 将 Tensor(张量)方言转换为 SPIR-V 方言。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-emulate-lt-32-bit-scalar-types` | Emulate narrower scalar types with 32-bit ones if not supported by the target | 当目标(target)不支持时,用 32 位类型模拟更窄的标量(scalar)类型 | | `-emulate-unsupported-float-types` | Emulate unsupported float types by representing them with integer types of same bit width | 通过用相同位宽(bit width)的整数类型来表示,来模拟不支持的浮点(float)类型 | ### -convert-to-emitc **EN:** Convert to EmitC dialect via dialect interfaces This is a generic pass to convert to the EmitC dialect, it uses the ConvertToEmitCPatternInterface dialect interface to delegate to dialects the injection of conversion patterns. **中文:** 通过方言(dialect)接口转换到 EmitC 方言。这是一个用于转换到 EmitC 方言的通用 Pass,它使用 `ConvertToEmitCPatternInterface` 方言接口,将注入转换 pattern(模式)的职责委派给各方言。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-filter-dialects` | Test conversion patterns of only the specified dialects | 仅测试所指定方言的转换 pattern(模式) | | `-lower-to-cpp` | Target C++ (true) instead of C (false) | 目标是 C++(true),而非 C(false) | ### -convert-to-llvm **EN:** Convert to LLVM via dialect interfaces found in the input IR This is a generic pass to convert to LLVM, it uses the ConvertToLLVMPatternInterface dialect interface to delegate to dialects the injection of conversion patterns. If dynamic is set to true , the pass will look for ConvertToLLVMAttrInterface attributes and use them to further configure the conversion process. This option also uses the DataLayoutAnalysis analysis to configure the type converter. Enabling this option incurs in extra overhead. **中文:** 通过输入 IR 中发现的方言(dialect)接口转换到 LLVM。这是一个用于转换到 LLVM 的通用 Pass,它使用 `ConvertToLLVMPatternInterface` 方言接口,将注入转换 pattern(模式)的职责委派给各方言。如果将 dynamic 设为 true,该 Pass 会查找 `ConvertToLLVMAttrInterface` 属性并使用它们来进一步配置转换过程。此选项还会使用 `DataLayoutAnalysis` 分析来配置类型转换器(type converter)。启用此选项会带来额外开销(overhead)。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-filter-dialects` | Test conversion patterns of only the specified dialects | 仅测试所指定方言的转换 pattern(模式) | | `-dynamic` | Use op conversion attributes to configure the conversion | 使用 op 转换属性来配置转换过程 | | `-allow-pattern-rollback` | Experimental performance flag to disallow pattern rollback | 用于禁止 pattern(模式)回滚(rollback)的实验性性能标志 | ### -convert-ub-to-llvm **EN:** Convert UB dialect to LLVM dialect This pass converts supported UB ops to LLVM dialect instructions. **中文:** 将 UB 方言转换为 LLVM 方言。该 Pass 将受支持的 UB op 转换为 LLVM 方言指令(instructions)。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-index-bitwidth` | Bitwidth of the index type, 0 to use size of machine word | index 类型的位宽,设为 0 表示使用机器字(machine word)的大小 | ### -convert-ub-to-spirv **EN:** Convert UB dialect to SPIR-V dialect This pass converts supported UB ops to SPIR-V dialect ops. **中文:** 将 UB 方言转换为 SPIR-V 方言。该 Pass 将受支持的 UB op 转换为 SPIR-V 方言的 op。 ### -convert-vector-to-amx **EN:** Lower the operations from the vector dialect into the X86 dialect AMX operations **中文:** 将 vector(向量)方言中的操作降低(lower)为 X86 方言的 AMX 操作。 ### -convert-vector-to-arm-sme **EN:** Lower the operations from the vector dialect into the ArmSME dialect Pass that converts vector dialect operations into equivalent ArmSME dialect operations. **中文:** 将 vector(向量)方言中的操作降低到 ArmSME 方言。该 Pass 将 vector 方言的操作转换为等价的 ArmSME 方言操作。 ### -convert-vector-to-gpu **EN:** Lower the operations from the vector dialect into the GPU dialect **中文:** 将 vector(向量)方言中的操作降低到 GPU 方言。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-use-nvgpu` | convert to NvGPU ops instead of GPU dialect ops | 转换为 NvGPU op,而非 GPU 方言的 op | ### -convert-vector-to-llvm **EN:** Lower the operations from the vector dialect into the LLVM dialect Convert operations from the vector dialect into the LLVM IR dialect operations. The lowering pass provides several options to control the kinds of optimizations that are allowed. It also provides options that enable the use of one or more architectural-specific dialects (X86, ArmNeon, ArmSVE, etc.) in combination with the architecturalneutral vector dialect lowering. **中文:** 将 vector(向量)方言中的操作降低到 LLVM 方言。将来自 vector 方言的操作转换为 LLVM IR 方言的操作。该降低(lowering)Pass 提供了若干选项,用以控制所允许的优化种类。它还提供了启用一个或多个架构特定(architectural-specific)方言(X86、ArmNeon、ArmSVE 等)的选项,可与架构中立(architectural-neutral)的 vector 方言降低方式组合使用。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-reassociate-fp-reductions` | Allows llvm to reassociate floating-point reductions for speed | 允许 LLVM 为提速而对浮点(floating-point)归约(reduction)进行重新结合(reassociation) | | `-force-32bit-vector-indices` | Allows compiler to assume vector indices fit in 32-bit if that yields faster code | 若这样能生成更快的代码,则允许编译器假设 vector 索引可容纳在 32 位内 | | `-use-vector-alignment` | Use the preferred alignment of a vector type in load/store operations instead of the alignment of the element type of the memref. This flag is intended for use with hardware which requiresvector alignment, or in application contexts where it is known all vector access are naturally aligned. If operations have an alignment attribute set, the alignment attribute takes priority over this option | 在 load/store 操作中使用某个 vector 类型的首选对齐(alignment),而非 memref 元素类型的对齐。此标志旨在用于要求 vector 对齐的硬件,或已知所有 vector 访问都是自然对齐的应用场景。如果操作设置了 alignment 属性,则该 alignment 属性优先于本选项 | | `-enable-gep-inbounds-nuw` | Emit inbounds\|nuw flags on GEPs generated by vector.load/store lowering. Assumes 0 <= idx < dim_size and non-negative strides for all dimensions. Setting this when those conditions do not hold is undefined behavior under the LLVM lowering. | 为 `vector.load/store` 降低生成的 GEP 发出 inbounds\|nuw 标志。假设对所有维度均满足 0 <= idx < dim_size 且步长(strides)非负。在那些条件不成立时设置本选项,在 LLVM 降低下属于未定义行为(undefined behavior)。 | | `-enable-arm-neon` | Enables the use of ArmNeon dialect while lowering the vector dialect. | 在降低 vector 方言时启用对 ArmNeon 方言的使用。 | | `-enable-arm-sve` | Enables the use of ArmSVE dialect while lowering the vector dialect. | 在降低 vector 方言时启用对 ArmSVE 方言的使用。 | | `-enable-arm-i8mm` | Enables the use of Arm FEAT_I8MM instructions while lowering the vector dialect. | 在降低 vector 方言时启用对 Arm FEAT_I8MM 指令的使用。 | | `-enable-arm-bf16` | Enables the use of Arm FEAT_BF16 instructions while lowering the vector dialect. | 在降低 vector 方言时启用对 Arm FEAT_BF16 指令的使用。 | | `-enable-x86` | Enables the use of X86 dialect while lowering the vector dialect. | 在降低 vector 方言时启用对 X86 方言的使用。 | | `-vector-contract-lowering` | control the lowering of `vector.contract` operations. | 控制 `vector.contract` 操作的降低方式。 | | `-vector-transpose-lowering` | control the lowering of `vector.transpose` operations. | 控制 `vector.transpose` 操作的降低方式。 | ### -convert-vector-to-scf **EN:** Lower the operations from the vector dialect into the SCF dialect **中文:** 将 vector(向量)方言中的操作降低到 SCF 方言。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-full-unroll` | Perform full unrolling when converting vector transfers to SCF | 在将 vector transfer 转换为 SCF 时执行完全展开(full unrolling) | | `-target-rank` | Target vector rank to which transfer ops should be lowered | transfer op 应降低到的目标 vector rank(秩/维数) | | `-lower-tensors` | Lower transfer ops that operate on tensors | 降低那些操作在 tensor 上的 transfer op | | `-lower-scalable` | Add scalable vector specific lowerings (that introduce loops) | 添加可扩展向量(scalable vector)特有的降低方式(会引入循环) | ### -convert-vector-to-spirv **EN:** Convert Vector dialect to SPIR-V dialect **中文:** 将 Vector(向量)方言转换为 SPIR-V 方言。 ### -convert-vector-to-xegpu **EN:** Lower the operations from the vector dialect into the XeGPU dialect **中文:** 将 vector(向量)方言中的操作降低到 XeGPU 方言。 ### -convert-xegpu-to-xevm **EN:** Convert XeGPU to XeVM dialect **中文:** 将 XeGPU 转换为 XeVM 方言。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-use-64bit-index` | Use 64-bit integers to convert index types | 使用 64 位整数来转换 index 类型 | --- ### -convert-xevm-to-llvm **EN:** Convert XeVM to LLVM dialect **中文:** 将 XeVM 转换为 LLVM 方言 ### -finalize-memref-to-llvm **EN:** Finalize MemRef dialect to LLVM dialect conversion **中文:** 完成(Finalize)从 MemRef 方言到 LLVM 方言的转换 **EN:** Finalize the conversion of the operations from the MemRef dialect to the LLVM dialect. This conversion will not convert some complex MemRef operations. Make sure to run expand-strided-metadata beforehand for these. **中文:** 完成将 MemRef 方言中的操作转换为 LLVM 方言。此转换不会处理某些复杂的 MemRef 操作,请务必事先对它们运行 expand-strided-metadata pass。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-use-aligned-alloc` | Use aligned_alloc in place of malloc for heap allocations | 堆内存分配时使用 aligned_alloc 代替 malloc | | `-index-bitwidth` | Bitwidth of the index type, 0 to use size of machine word | index 类型的位宽,取 0 表示使用机器字长(machine word)大小 | | `-use-generic-functions` | Use generic allocation and deallocation functions instead of the classic 'malloc', 'aligned_alloc' and 'free' functions | 使用通用的分配/释放函数代替经典的 'malloc'、'aligned_alloc' 和 'free' 函数 | ### -gpu-to-llvm **EN:** Convert GPU dialect to LLVM dialect with GPU runtime calls **中文:** 将 GPU 方言转换为带 GPU 运行时(runtime)调用的 LLVM 方言 **EN:** Creates a pass to convert a GPU operations into a sequence of GPU runtime calls. This pass does not generate code to call GPU runtime APIs directly but instead uses a small wrapper library that exports a stable and conveniently typed ABI on top of GPU runtimes such as CUDA or ROCm (HIP). **中文:** 创建一个 pass,将 GPU 操作转换为一系列 GPU 运行时调用。该 pass 不直接生成调用 GPU 运行时 API 的代码,而是使用一个小型包装库(wrapper library),它在 CUDA 或 ROCm(HIP)等 GPU 运行时之上导出稳定且类型方便的 ABI。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-use-bare-pointers-for-host` | Use bare pointers to pass memref arguments to host functions. All memrefs must have static shape. | 使用裸指针(bare pointer)向 host 函数传递 memref 参数。所有 memref 必须具有静态形状 | | `-use-bare-pointers-for-kernels` | Use bare pointers to pass memref arguments to kernels. The kernel must use the same setting for this option. | 使用裸指针向 kernel 传递 memref 参数。kernel 侧必须对本选项采用相同设置 | | `-intersperse-sizes-for-kernels` | Inserts a size_t argument following each memref argument, containing the static size in bytes of the buffer. Incompatible arguments are rejected. This is intended for use by the Vulkan runtime with the kernel bare pointer calling convention, to enable dynamic binding of buffers as arguments without static type info. | 在每个 memref 参数之后插入一个 size_t 参数,包含缓冲区的静态字节大小;不兼容的参数会被拒绝。该选项供 Vulkan 运行时配合 kernel 裸指针调用约定使用,以便在没有静态类型信息的情况下动态绑定作为参数的缓冲区 | ### -lift-cf-to-scf **EN:** Lift ControlFlow dialect to SCF dialect **中文:** 将 ControlFlow(控制流)方言提升(lift)到 SCF 方言 **EN:** Lifts ControlFlow operations to SCF dialect operations. This pass is prefixed with “lift” instead of “convert” as it is not always guaranteed to replace all ControlFlow ops. If a region contains only a single kind of return-like operation, all ControlFlow operations will be replaced successfully. Otherwise a single ControlFlow switch branching to one block per return-like operation kind remains. This pass may need to create unreachable terminators in case of infinite loops, which is only supported for ‘func.func’ for now. If you potentially have infinite loops inside CFG regions not belonging to ‘func.func’, consider using transformCFGToSCF function directly with corresponding CFGToSCFInterface::createUnreachableTerminator implementation. **中文:** 将 ControlFlow 操作提升为 SCF 方言的操作。该 pass 的前缀是 “lift”(提升)而非 “convert”(转换),因为无法保证总能替换掉所有 ControlFlow 操作。如果一个 region 只包含单一类型的 return-like(返回类)操作,则所有 ControlFlow 操作都能被成功替换;否则将残留一个 ControlFlow switch,按每种 return-like 操作类型分支到一个 block。对于无限循环的情况,该 pass 可能需要创建 unreachable terminator(不可达终止符),目前仅对 ‘func.func’ 提供支持。如果你可能在不属于 ‘func.func’ 的 CFG region 中存在无限循环,请考虑直接使用 transformCFGToSCF 函数并配合相应的 CFGToSCFInterface::createUnreachableTerminator 实现。 ### -lower-affine **EN:** Lower Affine operations to a combination of Arith and SCF operations **中文:** 将 Affine 操作降低(lower)为 Arith 与 SCF 操作的组合 **EN:** Convert operations from the affine dialect into operations from the SCF and standard dialects. affine.for operations are converted to scf.for operations that are free of certain structural restrictions (on their bounds and step). affine.if is similarly converted to the scf.if operation. affine.apply operations are converted into sequences of primitive arithmetic operations from the arith dialect that have the same effect, using operands of the index type. Consequently, named maps and sets thare are no longer in use may be removed from the module. **中文:** 将 affine 方言中的操作转换为 SCF 和 standard 方言的操作。affine.for 操作被转换为 scf.for 操作,后者不受某些结构性限制(对其边界 bounds 和步长 step 的限制)。affine.if 类似地被转换为 scf.if 操作。affine.apply 操作被转换为 arith 方言中一系列具有相同效果的原始算术操作,使用 index 类型的操作数。因此,不再使用的命名 map 和 set 可以从模块中移除。 **EN:** For example, %r = affine.apply affine_map<(d0, d1)[s0] -> (d0 + 2*d1 + s0)>(%d0, %d1)[%s0] can be converted into: **中文:** 例如,%r = affine.apply affine_map<(d0, d1)[s0] -> (d0 + 2*d1 + s0)>(%d0, %d1)[%s0] 可以被转换为: ```mlir %d0 = <...> %d1 = <...> %s0 = <...> %0 = arith.constant 2 : index %1 = arith.muli %0, %d1 %2 = arith.addi %d0, %1 %r = arith.addi %2, %s0 ``` **Input invariant / 输入不变量:** **EN:** no Tensor types; **中文:** 不含 Tensor(张量)类型; **EN:** These restrictions may be lifted in the future. **中文:** 这些限制未来可能会解除。 **Output IR / 输出 IR:** **EN:** Functions with affine.for and affine.if operations eliminated. These functions may contain operations from the Standard dialect in addition to those already present before the pass. **中文:** 函数中的 affine.for 和 affine.if 操作被消除。这些函数除了该 pass 之前已存在的操作外,还可能包含来自 Standard 方言的操作。 **Invariants / 不变量:** **EN:** Functions without a body are not modified. **中文:** 没有函数体(body)的函数不被修改。 **EN:** The semantics of the other functions is preserved. **中文:** 其他函数的语义保持不变。 **EN:** Individual operations other than those mentioned above are not modified if they do not depend on the loop iterator value or on the result of affine.apply . **中文:** 除上述提到的操作外,各个操作如果既不依赖于循环迭代器值,也不依赖于 affine.apply 的结果,则不被修改。 ### -lower-host-to-llvm **EN:** Lowers the host module code and gpu.launch_func to LLVM **中文:** 将 host 模块代码和 gpu.launch_func 降低到 LLVM **EN:** Creates a pass to emulate gpu.launch_func call in LLVM dialect and lower the host module code to LLVM. This transformation creates a sequence of global variables that are later linked to the variables in the kernel module, and a series of copies to/from them to emulate the memory transfer from the host or to the device sides. It also converts the remaining Arithmetic, Func, and MemRef dialects into LLVM dialect, emitting C wrappers. **中文:** 创建一个 pass,在 LLVM 方言中模拟 gpu.launch_func 调用并将 host 模块代码降低到 LLVM。该变换创建一系列全局变量(之后与 kernel 模块中的变量链接),以及一系列对它们的拷贝操作,用以模拟从 host 侧或向 device 侧的内存传输。它还将剩余的 Arithmetic、Func 和 MemRef 方言转换为 LLVM 方言,并生成 C wrapper(封装函数)。 ### -map-memref-spirv-storage-class **EN:** Map numeric MemRef memory spaces to SPIR-V storage classes **中文:** 将数值型 MemRef 内存空间映射到 SPIR-V 存储类(storage class) **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-client-api` | The client API to use for populating mappings | 用于填充映射的客户端 API | ### -raise-scf-to-affine **EN:** Raise SCF operations to affine operations (best effort) **中文:** 将 SCF 操作提升(raise)为 affine 操作(尽力而为,best effort) **EN:** Raising to the affine dialect enables affine analyses and transforms such as loop tiling, unrolling, vectorization, and dependence analysis. Currently only scf.for is handled; loops that cannot be raised are left unchanged. A scf.for is raised when its lower and upper bounds are valid affine dimensions (or an affine.max / affine.min respectively) and its step is a valid affine symbol. Two cases are handled: **中文:** 提升到 affine 方言可以启用 affine 分析与变换,例如循环分块(loop tiling)、展开(unrolling)、向量化(vectorization)和依赖分析(dependence analysis)。目前只处理 scf.for;无法提升的循环保持原样。当 scf.for 的下界和上界是合法的 affine dimension(或分别为一个 affine.max / affine.min),且其步长是合法的 affine symbol 时,该循环可被提升。分两种情况处理: **EN:** Constant step: raised directly, preserving the step and any affine.min / affine.max bounds as the loop’s bounds. **中文:** 常量步长(Constant step):直接提升,保留步长以及任何 affine.min / affine.max 边界作为循环的边界。 **EN:** Dynamic (symbolic) step: the loop is normalized to unit step and the original induction variable is reconstructed in the body. An affine.min upper bound is supported here; an affine.max lower bound is not, as it cannot be raised soundly without a constant step. **中文:** 动态(符号)步长:循环被归一化为单位步长,原始归纳变量(induction variable)在循环体内重建。此处支持 affine.min 上界;不支持 affine.max 下界,因为在没有常量步长的情况下无法可靠地(soundly)提升它。 **EN:** Bounds and step of non- index type are cast to index first if the source type allows lossless conversion (otherwise we do not touch the loop). In any case we preserve semantics. **中文:** 非 index 类型的边界和步长,如果源类型允许无损转换(lossless conversion),则先转换为 index(否则我们不改动该循环)。无论如何都会保持语义不变。 **EN:** This pass does not modify memory accesses; use --affine-raise-from-memref to convert memref.load / memref.store . **中文:** 该 pass 不修改内存访问;使用 --affine-raise-from-memref 来转换 memref.load / memref.store 。 ### -raise-wasm-mlir **EN:** Convert Wasm dialect to a group of dialect as a bridge to LLVM MLIR conversion **中文:** 将 Wasm 方言转换为若干方言,作为通往 LLVM MLIR 转换的桥梁 ### -reconcile-unrealized-casts **EN:** Simplify and eliminate unrealized conversion casts **中文:** 简化并消除未实现的转换 cast(unrealized_conversion_cast) **EN:** Eliminate unrealized_conversion_cast operations, commonly introduced by partial dialect conversions, that transitively convert a value to another value of the same type, that is: **中文:** 消除 unrealized_conversion_cast 操作——它们通常由部分方言转换引入,将一个值经过传递(transitively)转换为同一类型的另一个值,即: ```mlir %0 = "producer.op"() : () -> !type.A %1 = unrealized_conversion_cast %0 : !type.A to !type.B %2 = unrealized_conversion_cast %1 : !type.B to !type.C %3 = unrealized_conversion_cast %2 : !type.C to !type.A "consumer.op"(%3) : (!type.A) -> () ``` **EN:** Such situations appear when the consumer operation is converted by one pass and the producer operation is converted by another pass, each of which produces an unrealized cast. This pass can be used to clean up the IR. **中文:** 当消费方(consumer)操作由一个 pass 转换、而生产方(producer)操作由另一个 pass 转换时,就会出现这种情况,二者各自产生一个 unrealized cast。本 pass 可用于清理 IR。 ### -set-llvm-module-datalayout **EN:** Attach a datalayout string as a module attribute **中文:** 将 datalayout 字符串作为模块属性附加到模块上 **EN:** Verify that the dataLayout string is a valid LLVM datalayout string and attach it as an attribute LLVMDialect::getDataLayoutAttrName() to the module, overriding the existing one. **中文:** 校验 dataLayout 字符串是合法的 LLVM datalayout 字符串,并将其作为属性 LLVMDialect::getDataLayoutAttrName() 附加到模块上,覆盖已有的同名属性。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-data-layout` | String description (LLVM format) of the data layout that is expected on the produced module | 期望生成的模块所采用的数据布局的字符串描述(LLVM 格式) | ### -tosa-to-arith **EN:** Lower TOSA to the Arith dialect **中文:** 将 TOSA 降低到 Arith 方言 **EN:** Pass that converts TOSA operations to the equivalent operations using the operations in the Arith dialect. The ApplyScale operator is optionally included as it is often preserved until the final invocation. **中文:** 一个使用 Arith 方言中的操作将 TOSA 操作转换为等价操作的 pass。ApplyScale 算子可选择包含在内,因为它通常会被保留到最后一次调用(final invocation)。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-include-apply-rescale` | Whether to include the lowering for tosa.apply_rescale to arith | 是否包含 tosa.apply_rescale 到 arith 的降低(lowering) | | `-use-32-bit` | Whether to prioritze lowering to 32-bit operations | 是否优先降低为 32 位操作(原文拼写如此:prioritze) | ### -tosa-to-linalg **EN:** Lower TOSA to LinAlg on tensors **中文:** 将 TOSA 降低到作用于张量(tensor)上的 LinAlg **EN:** Pass that converts TOSA operations to the equivalent operations using the tensor operations in LinAlg. **中文:** 一个使用 LinAlg 中的张量操作将 TOSA 操作转换为等价操作的 pass。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-disable-tosa-decompositions` | Disable tosa decompositions pass | 禁用 tosa 分解(decomposition)pass | | `-aggressive-reduce-constant` | Always perform the reduce constant optimization | 始终执行 reduce 常量优化 | ### -tosa-to-linalg-named **EN:** Lower TOSA to LinAlg named operations **中文:** 将 TOSA 降低到 LinAlg 命名操作(named operations) **EN:** Pass that converts TOSA operations to the equivalent operations using the Linalg named operations. **中文:** 一个使用 Linalg 命名操作将 TOSA 操作转换为等价操作的 pass。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-prefer-conv2d-kernel-layout-hwcf` | Prefer generating linalg.conv_2d_nhwc_hwcf over linalg.conv_2d_nhwc_fhwc | 优先生成 linalg.conv_2d_nhwc_hwcf 而非 linalg.conv_2d_nhwc_fhwc | --- ### -tosa-to-mlprogram **EN:** Lower TOSA to the MLProgram dialect **中文:** 将 TOSA 降低(lower)到 MLProgram 方言(dialect)。 **EN:** Pass that converts TOSA’s variable operator operations to the equivalent MLProgram operations. **中文:** 该 Pass 把 TOSA 的变量算子操作转换为等价的 MLProgram 操作。 ### -tosa-to-scf **EN:** Lower TOSA to the SCF dialect **中文:** 将 TOSA 降低到 SCF 方言(dialect)。 **EN:** Pass that converts TOSA’s control flow operations to the equivalent SCF operations. **中文:** 该 Pass 把 TOSA 的控制流操作转换为等价的 SCF 操作。 ### -tosa-to-spirv-tosa **EN:** Lower TOSA IR to SPIR-V Graph/TOSA operations **中文:** 将 TOSA IR 降低到 SPIR-V Graph/TOSA 操作。 **EN:** Converts TOSA programs to the SPIR-V Graph/TOSA representation by wrapping converted functions in spirv.module and spirv.ARM.Graph , lowering supported TOSA ops to spirv.Tosa.* , and rewriting TOSA tensor and shape types to the corresponding SPIR-V ARM tensor types. **中文:** 通过将转换后的函数包裹在 `spirv.module` 与 `spirv.ARM.Graph` 中、将受支持的 TOSA 算子降低为 `spirv.Tosa.*`,并把 TOSA 的 tensor 与 shape 类型重写为对应的 SPIR-V ARM tensor 类型,从而把 TOSA 程序转换为 SPIR-V Graph/TOSA 表示。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-custom-op-domain-to-opcode` | Map TOSA custom op domains to spirv.ExperimentalML.Call opcodes. Entries use :. The option can be specified multiple times; if a domain appears more than once, the last mapping wins. | 将 TOSA 自定义算子(custom op)域映射到 `spirv.ExperimentalML.Call` 操作码(opcode)。条目格式为 `:`。该选项可多次指定;若同一域出现多次,以最后一次映射为准。 | ### -tosa-to-spirv-tosa-mark-graph-constants **EN:** Mark large TOSA constants as SPIR-V Graph constants **中文:** 将大型 TOSA 常量标记为 SPIR-V Graph 常量。 **EN:** Marks large tosa.const and tosa.const_shape operations so the TOSA-to-SPIR-V Graph/TOSA conversion lowers them to spirv.ARM.GraphConstant instead of inlining them as spirv.Constant . **中文:** 对大型的 `tosa.const` 与 `tosa.const_shape` 操作进行标记,使 TOSA 到 SPIR-V Graph/TOSA 的转换将它们降低为 `spirv.ARM.GraphConstant`,而不是将其内联(inline)为 `spirv.Constant`。 ### -tosa-to-tensor **EN:** Lower TOSA to the Tensor dialect **中文:** 将 TOSA 降低到 Tensor 方言(dialect)。 **EN:** Pass that converts TOSA operations to the equivalent operations using the operations in the Tensor dialect. **中文:** 该 Pass 借助 Tensor 方言中的操作,把 TOSA 操作转换为等价的操作。 --- ## ‘acc’ Dialect Passes(‘acc’ 方言 Pass) ### -acc-bind-routine **EN:** Apply bind clause to function calls in ACC compute regions **中文:** 将 bind 子句应用于 ACC 计算区域中的函数调用。 **EN:** For calls inside offload regions that target a function with an acc routine directive and a bind(name) clause, rewrite the call to use the bound symbol so device code calls the correct call target. **中文:** 对于 offload 区域内指向带有 `acc routine` 指令和 `bind(name)` 子句的函数的调用,将该调用重写为使用绑定(bound)符号,从而确保设备代码调用正确的调用目标。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-device-type` | Target device type. One use case is ensuring that device_type-specific clauses are considered. Another is device-specific specializations. | 目标设备类型。一个用途是确保考虑 device_type 特定的子句;另一个用途是设备特定的特化(specialization)。 | ### -acc-cg-to-gpu **EN:** Lower acc.compute_region to gpu.launch **中文:** 将 `acc.compute_region` 降级为 `gpu.launch`。 **EN:** Generate GPU code for acc.compute_region loop nests by converting them to gpu.launch and mapping acc.par_dims parallelism to GPU block and thread dimensions. **中文:** 通过将 `acc.compute_region` 转换为 `gpu.launch`,并把 `acc.par_dims` 的并行性映射到 GPU 的 block(块)和 thread(线程)维度,为 `acc.compute_region` 循环嵌套生成 GPU 代码。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-device-type` | Target device type. One use case is ensuring that device_type-specific clauses are considered. Another is device-specific specializations. | 目标设备类型。一个用途是确保考虑 device_type 特定的子句;另一个用途是设备特定的特化(specialization)。 | | `-max-workgroup-shared-memory` | Maximum workgroup shared memory budget in bytes. | workgroup 共享内存预算上限(单位:字节)。 | | `-max-thread-private-stack` | Maximum thread-private stack allocation in bytes. | 线程私有栈分配上限(单位:字节)。 | | `-subgroup-size` | Subgroup size used for block-dimension alignment and reductions. | 用于 block 维度对齐和归约(reduction)的 subgroup 大小。 | ### -acc-compute-lowering **EN:** Lower ACC compute constructs to acc.compute_region **中文:** 将 ACC 计算构造降级为 `acc.compute_region`。 **EN:** Converts ACC frontend compute constructs (acc.parallel, acc.kernels, acc.serial) to acc.compute_region wrapped in acc.kernel_environment. Converts acc.loop to SCF parallel/for loops with parallel dimension annotations. **中文:** 将 ACC 前端的计算构造(`acc.parallel`、`acc.kernels`、`acc.serial`)转换为包裹在 `acc.kernel_environment` 中的 `acc.compute_region`。将 `acc.loop` 转换为带并行维度注解的 SCF parallel/for 循环。 **EN:** The pass applies two phases of pattern rewrites: **中文:** 该 Pass 应用两个阶段的模式重写(pattern rewrite): 1. **EN:** Loop conversion: acc.loop is converted to scf.parallel or scf.for while the parent compute construct is still present (needed to determine loop conversion strategy). **中文:** 循环转换:在父计算构造仍然存在时将 `acc.loop` 转换为 `scf.parallel` 或 `scf.for`(需要它来确定循环转换策略)。 2. **EN:** Compute construct conversion: acc.parallel, acc.kernels, and acc.serial are replaced by acc.kernel_environment containing acc.compute_region. **中文:** 计算构造转换:将 `acc.parallel`、`acc.kernels` 和 `acc.serial` 替换为包含 `acc.compute_region` 的 `acc.kernel_environment`。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-device-type` | Target device type. One use case is ensuring that device_type-specific clauses are considered. Another is device-specific specializations. | 目标设备类型。一个用途是确保考虑 device_type 特定的子句;另一个用途是设备特定的特化(specialization)。 | ### -acc-declare-gpu-module-insertion **EN:** Copy globals with acc.declare into the GPU module **中文:** 将带有 `acc.declare` 的全局变量复制到 GPU 模块中。 **EN:** Copies globals that have the acc.declare attribute into the GPU module so that device code can reference them. **中文:** 将具有 `acc.declare` 属性的全局变量复制到 GPU 模块中,以便设备代码能够引用它们。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-cuda-unified` | Emit declaration-only device globals for CUDA unified memory. | 为 CUDA 统一内存(unified memory)发出仅含声明的设备端全局变量。 | ### -acc-emit-remarks-data **EN:** Emit OpenACC data-mapping remarks **中文:** 发出 OpenACC 数据映射 remark。 **EN:** This pass emits remarks describing the data clauses associated with OpenACC data constructs and unstructured data directives. **中文:** 该 Pass 发出描述与 OpenACC 数据构造和非结构化(unstructured)数据指令相关联的数据子句的 remark。 ### -acc-emit-remarks-loop **EN:** Emit OpenACC loop parallelism mapping remarks **中文:** 发出 OpenACC 循环并行性映射 remark。 **EN:** This pass emits optimization remarks describing how loops inside OpenACC compute regions are mapped to parallelism levels (gang, worker, vector, sequential) and the corresponding GPU parallel dimensions. **中文:** 该 Pass 发出优化 remark,描述 OpenACC 计算区域内的循环如何映射到并行级别(gang、worker、vector、sequential)以及对应的 GPU 并行维度。 **EN:** The pass walks acc.compute_region operations that originated from OpenACC compute constructs and reports remarks for each loop carrying an acc.par_dims attribute. **中文:** 该 Pass 遍历源自 OpenACC 计算构造的 `acc.compute_region` 操作,并为每个携带 `acc.par_dims` 属性的循环报告 remark。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-gpu-dim-separator` | Separator between GPU index prefix and axis name in remarks | remark 中 GPU 索引前缀与轴名之间的分隔符。 | ### -acc-emit-remarks-private **EN:** Emit OpenACC private and firstprivate remarks **中文:** 发出 OpenACC `private` 和 `firstprivate` remark。 **EN:** This pass emits optimization remarks describing the private and firstprivate variables associated with OpenACC compute and loop constructs. The pass walks compute constructs and acc.loop operations and, for each, reports the implicit and explicit private and firstprivate variables it carries. **中文:** 该 Pass 发出描述与 OpenACC 计算构造和循环构造相关联的 `private` 及 `firstprivate` 变量的优化 remark。该 Pass 遍历各计算构造和 `acc.loop` 操作,并针对每一个报告其携带的隐式和显式的 `private`、`firstprivate` 变量。 ### -acc-if-clause-lowering **EN:** Lower if clauses in ACC compute constructs **中文:** 降级 ACC 计算构造中的 `if` 子句。 **EN:** This pass lowers OpenACC compute constructs (parallel, kernels, serial) with if clauses using region specialization. It creates two execution paths: device execution when the condition is true, host execution when false. **中文:** 该 Pass 使用区域特化(region specialization)来降级带有 `if` 子句的 OpenACC 计算构造(parallel、kernels、serial)。它创建两条执行路径:条件为真时走设备端执行,为假时走主机端执行。 **EN:** When an ACC compute construct has an if clause, the construct should only execute on the device when the condition is true. If the condition is false, the code should execute on the host instead. This pass transforms: **中文:** 当 ACC 计算构造带有 `if` 子句时,该构造只应在条件为真时在设备上执行;如果条件为假,代码应改在主机上执行。该 Pass 将如下变换: ``` acc.parallel if(%cond) { ... } ``` **EN:** Into: **中文:** 变为: ``` scf.if %cond { // Device path: clone data ops, compute construct without if, exit ops acc.parallel { ... } } else { // Host path: original region body with ACC ops converted to host } ``` **EN:** The transformation handles: **中文:** 该变换处理的内容包括: - **EN:** Data entry operations (acc.copyin, acc.create, etc.) are cloned to device path **中文:** 数据入口操作(`acc.copyin`、`acc.create` 等)被克隆到设备路径。 - **EN:** Data exit operations (acc.copyout, acc.delete, etc.) are cloned to device path **中文:** 数据出口操作(`acc.copyout`、`acc.delete` 等)被克隆到设备路径。 - **EN:** The host path uses populateACCHostFallbackPatterns to convert ACC ops **中文:** 主机路径使用 `populateACCHostFallbackPatterns` 来转换 ACC 操作。 ### -acc-implicit-data **EN:** Generate implicit data attributes for OpenACC compute constructs **中文:** 为 OpenACC 计算构造生成隐式数据属性。 **EN:** This pass implements the OpenACC specification for “Variables with Implicitly Determined Data Attributes” (OpenACC 3.4 spec, section 2.6.2). **中文:** 该 Pass 实现了 OpenACC 规范中关于“隐式确定数据属性的变量(Variables with Implicitly Determined Data Attributes)”的规定(OpenACC 3.4 规范,第 2.6.2 节)。 **EN:** The pass automatically generates data clause operations for variables used within OpenACC compute constructs (parallel, kernels, serial) that do not already have explicit data clauses. The semantics follow these rules: **中文:** 对于在 OpenACC 计算构造(parallel、kernels、serial)内使用且尚未具有显式数据子句的变量,该 Pass 自动生成数据子句操作。其语义遵循以下规则: 1. **EN:** If there is a default(none) clause visible, no implicit data actions apply. **中文:** 如果可见(visible)一个 `default(none)` 子句,则不适用任何隐式数据动作。 2. **EN:** An aggregate variable (arrays, derived types, etc.) will be treated as: In a present clause when default(present) is visible. In a copy clause otherwise. **中文:** 聚合变量(数组、派生类型等)将被视为:当可见 `default(present)` 时按 `present` 子句处理;否则按 `copy` 子句处理。 3. **EN:** A scalar variable will be treated as if it appears in: A copy clause if the compute construct is a kernels construct. A firstprivate clause otherwise (parallel, serial). **中文:** 标量变量将被视为出现在:若计算构造是 kernels 构造,则按 `copy` 子句;否则(parallel、serial)按 `firstprivate` 子句。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-enable-implicit-reduction-copy` | Enable applying implicit copy in lieu of implicit firstprivate for reduction variables. This allows uniform treatment of reduction variables between combined constructs (e.g., 'parallel loop') and separate constructs (e.g., 'parallel' followed by 'loop'), where the OpenACC spec requires copy semantics for the former but firstprivate would normally apply for the latter. | 对归约(reduction)变量启用以隐式 `copy` 代替隐式 `firstprivate`。这使得归约变量在组合构造(如 `'parallel loop'`)与分离构造(如 `'parallel'` 后接 `'loop'`)之间可以统一处理——OpenACC 规范要求前者使用 copy 语义,而后者通常适用 firstprivate。 | | `-ignore-default-none` | When disabled (default), if the region has a default(none) clause, this pass does not generate implicit data attributes. When enabled, implicit data is generated even with default(none). This is useful when the frontend has robust default(none) verification: user variables are already verified, so any remaining live-ins are variables that still need mapping handling. | 禁用时(默认),若区域带有 `default(none)` 子句,该 Pass 不生成隐式数据属性;启用后即使存在 `default(none)` 也会生成隐式数据。当前端具备健壮的 `default(none)` 校验时非常有用:用户变量已经过校验,因此剩余的 live-in(活跃输入)就是仍需要映射处理的变量。 | ### -acc-implicit-declare **EN:** Applies implicit acc declare to globals referenced in compute and routine acc regions **中文:** 对计算区域和 routine 区域内引用的全局变量应用隐式 `acc declare`。 **EN:** This pass applies implicit acc declare actions to global variables referenced in OpenACC compute regions and routine functions. **中文:** 该 Pass 对在 OpenACC 计算区域和 routine 函数中引用的全局变量应用隐式 `acc declare` 动作。 **EN:** The pass performs the following actions: **中文:** 该 Pass 执行以下操作: 1. **EN:** Hoists address-of operations for non-constant globals out of OpenACC regions when they can be implicitly mapped rather than declared. **中文:** 当非常量全局变量可以隐式映射而非声明时,将其取地址(address-of)操作提升(hoist)出 OpenACC 区域。 2. **EN:** Collects global symbols referenced in: OpenACC compute constructs (parallel, kernels, serial) Functions marked with acc routine Initialization regions of existing acc declare globals Private/firstprivate/reduction recipe operations **中文:** 收集在以下位置引用的全局符号:OpenACC 计算构造(parallel、kernels、serial);标记了 `acc routine` 的函数;现有 `acc declare` 全局变量的初始化区域;`private`/`firstprivate`/`reduction` recipe 操作。 3. **EN:** Marks collected globals with the acc.declare attribute using the copyin data clause. **中文:** 使用 `copyin` 数据子句,为收集到的全局变量标记 `acc.declare` 属性。 **EN:** The pass avoids unnecessary declare marking by: **中文:** 该 Pass 通过以下方式避免不必要的 declare 标记: - **EN:** Skipping function symbols (which use acc routine instead) **中文:** 跳过函数符号(它们改用 `acc routine`)。 - **EN:** Hoisting non-constant global references that can use implicit mapping **中文:** 提升可以使用隐式映射的非常量全局引用。 - **EN:** Only processing symbols that are not already valid in device regions **中文:** 只处理在设备区域中尚不有效的符号。 ### -acc-implicit-routine **EN:** Generate implicit acc routine for functions in acc regions **中文:** 为 `acc` 区域内的函数生成隐式 `acc routine`。 **EN:** This pass implements the implicit rules described in OpenACC specification for Routine Directive (OpenACC 3.4 spec, section 2.15.1). **中文:** 该 Pass 实现了 OpenACC 规范中关于 Routine 指令的隐式规则(OpenACC 3.4 规范,第 2.15.1 节)。 **EN:** “If no explicit routine directive applies to a procedure whose definition appears in the program unit being compiled, then the implementation applies an implicit routine directive to that procedure if any of the following conditions holds: The procedure is called or its address is accessed in a compute region.” **中文:** “如果被编译的程序单元中出现定义的某个过程(procedure)不适用任何显式 routine 指令,且满足以下任一条件,则实现应针对该过程应用隐式 routine 指令:该过程在计算区域中被调用或其地址被访问。” **EN:** The specification further states: “When the implementation applies an implicit routine directive to a procedure, it must recursively apply implicit routine directives to other procedures for which the above rules specify relevant dependencies. Such dependencies can form a cycle, so the implementation must take care to avoid infinite recursion.” **中文:** 规范进一步指出:“当实现为某个过程应用隐式 routine 指令时,它必须对上述规则规定了相关依赖的其他过程递归地应用隐式 routine 指令。这些依赖可能形成环,因此实现必须小心避免无限递归。” **EN:** This pass implements these requirements by: **中文:** 该 Pass 通过以下方式实现这些要求: 1. **EN:** Walking through all OpenACC compute constructs and functions already marked with acc routine in the module and identifying function calls within these regions. **中文:** 遍历模块中所有 OpenACC 计算构造以及已标记 `acc routine` 的函数,并识别这些区域内的函数调用。 2. **EN:** Creating implicit acc.routine operations for functions that don’t already have routine declarations. **中文:** 为尚未具有 routine 声明的函数创建隐式 `acc.routine` 操作。 3. **EN:** Recursively walking through all existing acc routine and creating implicit routine operations for function calls within these routines, while avoiding infinite recursion through proper tracking. **中文:** 递归遍历所有现有的 `acc routine`,为这些 routine 内的函数调用创建隐式 routine 操作,同时通过恰当的记录跟踪避免无限递归。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-device-type` | Target device type. One use case is ensuring that device_type-specific clauses are considered. Another is device-specific specializations. | 目标设备类型。一个用途是确保考虑 device_type 特定的子句;另一个用途是设备特定的特化(specialization)。 | ### -acc-legalize-serial **EN:** Legalize OpenACC serial constructs **中文:** 规范化(legalize)OpenACC `serial` 构造。 **EN:** This pass converts acc.serial constructs into acc.parallel constructs with num_gangs(1), num_workers(1), and vector_length(1). **中文:** 该 Pass 将 `acc.serial` 构造转换为带有 `num_gangs(1)`、`num_workers(1)` 和 `vector_length(1)` 的 `acc.parallel` 构造。 **EN:** This transformation simplifies processing of acc regions by unifying the handling of serial and parallel constructs. Since an OpenACC serial region executes sequentially (like a parallel region with a single gang, worker, and vector), this conversion is semantically equivalent while enabling code reuse in later compilation stages. **中文:** 该变换通过统一处理 `serial` 与 `parallel` 构造,简化了对 `acc` 区域的处理。由于 OpenACC `serial` 区域是顺序执行的(相当于只有一个 gang、worker 和 vector 的 parallel 区域),这一转换在语义上是等价的,同时使后续编译阶段可以复用代码。 --- ### -acc-loop-tiling **EN:** Tile OpenACC loops with tile clauses **中文:** 使用 tile 子句对 OpenACC 循环进行分块(tile) **EN:** This pass implements loop tiling transformations for OpenACC loops that have tile clauses. The pass transforms loops with tile(size1, size2, ...) clauses into tiled loop nests. **中文:** 该 pass 为带有 tile 子句的 OpenACC 循环实现循环分块(loop tiling)变换,将带 tile(size1, size2, ...) 子句的循环变换为分块后的循环嵌套(tiled loop nest)。 **EN:** For a 2-level nested loop with tile(T1, T2), the transformation produces: - Outer tile loops that iterate over tiles - Inner element loops that iterate within each tile **中文:** 对于带 tile(T1, T2) 的二级嵌套循环,该变换产生: - 外层 tile 循环(遍历各个 tile) - 内层元素循环(在每个 tile 内部遍历) **Example transformation / 变换示例:** ```c // Before: #pragma acc loop tile(32, 32) for (i = 0; i < N; i++) for (j = 0; j < M; j++) A[i][j] = ... // After: for (i = 0; i < N; i += 32) for (j = 0; j < M; j += 32) // tile loop 1 // tile loop 2 for (ii = i; ii < min(N, i+32); ii++) for (jj = j; jj < min(M, j+32); jj++) // element loop 1 // element loop 2 A[ii][jj] = ... ``` **EN:** The pass handles: - Constant tile sizes - Wildcard tile sizes (’*’) which use a default tile size - Collapsed loops with tile counts exceeding collapse count - Proper handling of loop attributes (gang, worker, vector) **中文:** 该 pass 处理: - 常量 tile 尺寸 - 通配符 tile 尺寸(‘*’),使用默认 tile 尺寸 - tile 数量超过 collapse 数量的 collapsed 循环 - 正确处理循环属性(gang、worker、vector) **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-default-tile-size` | Default tile size to use for wildcard ('*') tile sizes | 用于通配符('*')tile 尺寸的默认 tile 尺寸 | ### -acc-recipe-materialization **EN:** Materialize OpenACC private, firstprivate and reduction recipes **中文:** 物化(materialize)OpenACC 的 private、firstprivate 与 reduction recipe **EN:** Materializes OpenACC privatization, firstprivate and reduction recipes by cloning init, copy, combiner, and destroy into the construct. Replaces recipe references with materialized values (including acc.reduction_init and acc.reduction_combine_region for reductions) and removes unused recipe symbols. **中文:** 通过将 init、copy、combiner 和 destroy 克隆到构造(construct)内部,来物化 OpenACC 的 privatization、firstprivate 和 reduction recipe;将 recipe 引用替换为物化后的值(对 reduction 还包括 acc.reduction_init 与 acc.reduction_combine_region),并删除未使用的 recipe symbol。 ### -acc-routine-lowering **EN:** Specialize acc routine functions for device **中文:** 针对设备(device)特化 acc routine 函数 **EN:** This pass handles acc routine directive by creating specialized functions with appropriate parallelism information that can be used for eventual creation of device function. **中文:** 该 pass 处理 acc routine 指令,创建带有适当并行度信息的特化函数,以便最终用于创建设备(device)函数。 **EN:** For each acc.routine that is not bound by name, the pass creates a new function (the "device" copy) whose body is a single acc.compute_region containing a clone of the original (host) function body. Parallelism is expressed by one acc.par_width derived from the routine’s clauses (seq, vector, worker, gang). The pass does not use acc.kernel_environment. It sets acc.specialized_routine on the new function and updates the acc.routine’s func_name to point to it. Routines with bind(name) and external functions are skipped. **中文:** 对于每个未以名称绑定(not bound by name)的 acc.routine,该 pass 会创建一个新函数("device" 副本),其函数体是单一的 acc.compute_region,其中包含原(host)函数体的克隆。并行度由一个源自 routine 子句(seq、vector、worker、gang)的 acc.par_width 表达。该 pass 不使用 acc.kernel_environment;它在新函数上设置 acc.specialized_routine,并更新 acc.routine 的 func_name 使其指向新函数。带有 bind(name) 的 routine 和外部函数会被跳过。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-device-type` | Target device type. One use case is ensuring that device_type-specific clauses are considered. Another is device-specific specializations. | 目标设备类型。一个用途是确保考虑 device_type 特定的子句;另一个用途是设备专属的特化(specialization)。 | ### -acc-routine-to-gpu-func **EN:** Move ACC routine functions into the GPU module as gpu.func **中文:** 将 ACC routine 函数以 gpu.func 形式移入 GPU module **EN:** This pass moves functions associated with acc routine (and any callees that must be present on the device) into the GPU module as gpu.func operations. **中文:** 该 pass 将与 acc routine 关联的函数(以及必须存在于设备上的任何被调用者)作为 gpu.func 操作移入 GPU module。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-device-type` | Target device type. One use case is ensuring that device_type-specific clauses are considered. Another is device-specific specializations. | 目标设备类型。一个用途是确保考虑 device_type 特定的子句;另一个用途是设备专属的特化(specialization)。 | ### -acc-specialize-for-device **EN:** Strip OpenACC constructs inside device code **中文:** 去除设备代码内部的 OpenACC 构造 **EN:** In a specialized acc routine or compute construct, many OpenACC operations do not make sense because they are host-side constructs. This pass removes or transforms these operations appropriately. **中文:** 在特化的 acc routine 或 compute 构造中,许多 OpenACC 操作没有意义,因为它们是 host 侧的构造。该 pass 会适当地移除或变换这些操作。 **EN:** The following operations are handled: - Data entry ops (replaced with var): acc.attach, acc.copyin, acc.create, acc.declare_device_resident, acc.declare_link, acc.deviceptr, acc.get_deviceptr, acc.nocreate, acc.present, acc.update_device, acc.use_device - Data exit ops (erased): acc.copyout, acc.delete, acc.detach, acc.update_host - Structured data (inline region): acc.data, acc.host_data, acc.kernel_environment - Unstructured data (erased): acc.enter_data, acc.exit_data, acc.update, acc.declare_enter, acc.declare_exit - Compute constructs (inline region): acc.parallel, acc.serial, acc.kernels - Runtime ops (erased): acc.init, acc.shutdown, acc.set, acc.wait (folded if known): acc.on_device **中文:** 以下操作会被处理: - 数据入口 op(替换为 var):acc.attach、acc.copyin、acc.create、acc.declare_device_resident、acc.declare_link、acc.deviceptr、acc.get_deviceptr、acc.nocreate、acc.present、acc.update_device、acc.use_device - 数据出口 op(删除):acc.copyout、acc.delete、acc.detach、acc.update_host - 结构化数据(内联区域):acc.data、acc.host_data、acc.kernel_environment - 非结构化数据(删除):acc.enter_data、acc.exit_data、acc.update、acc.declare_enter、acc.declare_exit - compute 构造(内联区域):acc.parallel、acc.serial、acc.kernels - 运行时 op(删除):acc.init、acc.shutdown、acc.set、acc.wait;(若已知则折叠 folded):acc.on_device **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-the-device-types` | List of integers which represent the device we are specializing for | 表示正在为其做特化的设备的整数列表 | ### -acc-specialize-for-host **EN:** Convert OpenACC operations for host execution **中文:** 将 OpenACC 操作转换为可用于 host 执行的形态 **EN:** This pass converts OpenACC operations to host-compatible representations. It serves as a conversion pass that transforms ACC constructs to enable execution on the host rather than on accelerator devices. **中文:** 该 pass 将 OpenACC 操作转换为 host 兼容的表示。它作为一个转换(conversion)pass,变换 ACC 构造以便在 host 而非加速器设备上执行。 **EN:** There are two modes of operation: 1. Default mode (orphan operations only): Only orphan operations that are not allowed outside compute regions are converted. Structured/unstructured data constructs, compute constructs, and their associated data operations are NOT removed. 2. Host fallback mode (enableHostFallback=true): ALL ACC operations within the region are converted to host equivalents. This is used when the if clause evaluates to false at runtime. **中文:** 有两种工作模式: 1. 默认模式(仅孤儿操作):只转换不允许出现在 compute region 之外的孤儿操作(orphan operations)。结构化/非结构化数据构造、compute 构造及其关联的数据操作不会被移除。 2. host 回退模式(enableHostFallback=true):区域内的所有 ACC 操作都会被转换为 host 等价形式。当 if 子句在运行时求值为 false 时使用该模式。 **EN:** The following operations are handled: - Atomic ops: converted to load/store operations - Loop ops: converted to scf.for or scf.execute_region - Data entry ops (orphan): replaced with var operand - In host fallback mode: all data, compute, and runtime ops are removed **中文:** 以下操作会被处理: - 原子 op:转换为 load/store 操作 - 循环 op:转换为 scf.for 或 scf.execute_region - 数据入口 op(孤儿):替换为 var 操作数 - 在 host 回退模式下:所有 data、compute 和 runtime op 都会被移除 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-enable-host-fallback` | Enable host fallback mode which converts ALL ACC operations, not just orphan operations. Use this when the `if` clause evaluates to false. | 启用 host 回退模式,该模式会转换所有 ACC 操作,而不仅仅是孤儿操作。当 `if` 子句求值为 false 时使用。 | ### -offload-livein-value-canonicalization **EN:** Canonicalize live-in values for regions destined for outlining **中文:** 规范化(canonicalize)准备用于 outline 的区域的 live-in 值 **EN:** This pass canonicalizes live-in values for regions destined for outlining. It handles operations that produce synthetic types or values that cannot be passed as arguments to outlined regions. **中文:** 该 pass 规范化那些准备被 outline(外提)的区域的 live-in 值。它处理那些产生无法作为参数传入 outlined region 的合成类型或值的操作。 **EN:** The pass performs the following transformations: 1. Sinking: Operations whose results are only used inside the region are moved into the region. This reduces the number of live-in values and keeps related operations together. 2. Rematerialization: Operations whose results are used both inside and outside the region are cloned into the region. The uses inside the region are updated to use the cloned operation’s results. **中文:** 该 pass 执行以下变换: 1. 下沉(sinking):结果仅在区域内部使用的操作会被移入该区域。这减少了 live-in 值的数量,并让相关操作保持在一起。 2. 重物质化(rematerialization):结果在区域内外部都被使用的操作会被克隆进该区域;区域内的使用点会更新为使用克隆操作的結果。 **EN:** Operations are considered candidates for these transformations if they implement the OutlineRematerializationOpInterface or match constant patterns. These operations typically produce synthetic types (shapes, bounds, field indices) that cannot be passed as function arguments. **中文:** 如果一个 op 实现了 OutlineRematerializationOpInterface 或匹配常量模式,它就被视为这些变换的候选。这类操作通常产生无法作为函数参数传递的合成类型(shape、bounds、field index)。 **EN:** The pass iterates until convergence since canonicalizing one value may expose new candidates (e.g., a bounds operation’s operands may themselves be constants that should be rematerialized). **中文:** 由于规范化一个值可能会暴露新的候选,该 pass 会迭代直到收敛(例如,某个 bounds 操作的运算子本身可能就是应当被重物质化的常量)。 **Example transformation (rematerialization) / 变换示例(rematerialization):** ```mlir // Before: %c0 = arith.constant 0 : index %c10 = arith.constant 10 : index %bounds = acc.bounds lowerbound(%c0 : index) upperbound(%c10 : index) acc.parallel { %priv = acc.private varPtr(%ptr : ...) bounds(%bounds) -> ... acc.yield } // %bounds is also used elsewhere // After: %c0 = arith.constant 0 : index %c10 = arith.constant 10 : index %bounds = acc.bounds lowerbound(%c0 : index) upperbound(%c10 : index) acc.parallel { %c0_clone = arith.constant 0 : index %c10_clone = arith.constant 10 : index %bounds_clone = acc.bounds lowerbound(%c0_clone : index) upperbound(%c10_clone : index) %priv = acc.private varPtr(%ptr : ...) bounds(%bounds_clone) -> ... acc.yield } ``` **Example transformation (sinking) / 变换示例(sinking):** ```mlir // Before: %c0 = arith.constant 0 : index %c10 = arith.constant 10 : index %bounds = acc.bounds lowerbound(%c0 : index) upperbound(%c10 : index) acc.parallel { %priv = acc.private varPtr(%ptr : ...) bounds(%bounds) -> ... acc.yield } // %bounds is NOT used elsewhere // After: acc.parallel { %c0 = arith.constant 0 : index %c10 = arith.constant 10 : index %bounds = acc.bounds lowerbound(%c0 : index) upperbound(%c10 : index) %priv = acc.private varPtr(%ptr : ...) bounds(%bounds) -> ... acc.yield } ``` ### -offload-target-verifier **EN:** Verify values and symbols live into offload regions for legality **中文:** 校验 live into offload region 的 value 和 symbol 是否合法 **EN:** This pass verifies that values and symbols used within OpenACC compute constructs and other offload regions are legal for the target execution model. **中文:** 该 pass 校验在 OpenACC compute 构造和其他 offload region 中使用的值与符号,对目标执行模型而言是否合法。 **EN:** The pass performs two main checks: 1. Live-in Value Verification: Checks that all values that are live into an offload region are valid for use in that region. This includes checking that pointer-like and mappable types have appropriate data clauses or device attributes. 2. Symbol Use Verification: Checks that all symbol references within an offload region are valid for that region. This includes checking for acc.routine declarations and acc.declare attributes. **中文:** 该 pass 执行两项主要检查: 1. Live-in 值校验(Live-in Value Verification):检查所有 live into offload region 的值在该区域中是否可被合法使用,包括检查指针类(pointer-like)和可映射(mappable)类型是否具有恰当的数据子句或设备属性。 2. 符号使用校验(Symbol Use Verification):检查 offload region 内的所有符号引用对该区域是否有效,包括检查 acc.routine 声明和 acc.declare 属性。 **EN:** The device_type option notes the target execution model: - none , nvidia , radeon : Device execution (GPU offload) - host , multicore : Host execution **中文:** device_type 选项指明目标执行模型: - none、nvidia、radeon:设备执行(GPU offload) - host、multicore:host 执行 **EN:** When soft_check is enabled, the pass only emits debug messages for illegal values/symbols instead of failing compilation. This is useful for diagnostic purposes. **中文:** 当启用 soft_check 时,该 pass 仅对非法的 value/symbol 输出调试信息,而不是使编译失败。这可用于诊断目的。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-device-type` | Target device type. One use case is ensuring that device_type-specific clauses are considered. Another is device-specific specializations. | 目标设备类型。一个用途是确保考虑 device_type 特定的子句;另一个用途是设备专属的特化(specialization)。 | | `-soft-check` | When true, illegal values are printed via LLVM_DEBUG instead of failing compilation. Useful for diagnostic purposes. | 为 true 时,非法值会通过 LLVM_DEBUG 打印出来而不是使编译失败。可用于诊断目的。 | ### -openacc-legalize-data-values **EN:** Legalizes SSA values in compute regions with results from data clause operations **中文:** 用数据子句操作的结果规范化(legalize)compute region 中的 SSA 值 **EN:** This pass replace uses of the varPtr in compute regions (kernels, parallel, serial) with the result of data clause operations ( accPtr ). **中文:** 该 pass 将 compute region(kernels、parallel、serial)中对 varPtr 的使用替换为数据子句操作的结果( accPtr )。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-host-to-device` | Replace varPtr uses with accPtr if true. Replace accPtr uses with varPtr if false | 为 true 时,将 varPtr 的使用替换为 accPtr;为 false 时,将 accPtr 的使用替换为 varPtr | | `-apply-to-acc-data-construct` | Replaces varPtr uses with accPtr for acc compute regions contained within acc.data or acc.declare region. | 对包含在 acc.data 或 acc.declare region 内的 acc compute region,将 varPtr 的使用替换为 accPtr | --- ## 'affine' Dialect Passes('affine' 方言 Pass) ### -affine-data-copy-generate **EN:** Generate explicit copying for affine memory operations **中文:** 为 affine 内存操作生成显式拷贝 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-fast-mem-capacity` | Set fast memory space capacity in KiB (default: unlimited) | 设置快速内存空间容量(单位 KiB)(默认:无限制) | | `-fast-mem-space` | Fast memory space identifier for copy generation (default: 1) | 用于生成拷贝的快速内存空间标识符(默认:1) | | `-generate-dma` | Generate DMA instead of point-wise copy | 生成 DMA 而非逐点拷贝 | | `-min-dma-transfer` | Minimum DMA transfer size supported by the target in bytes | 目标硬件支持的最小 DMA 传输大小(字节) | | `-slow-mem-space` | Slow memory space identifier for copy generation (default: 0) | 用于生成拷贝的慢速内存空间标识符(默认:0) | | `-skip-non-unit-stride-loops` | Testing purposes: avoid non-unit stride loop choice depths for copy placement | 测试用途:避免为放置拷贝位置而选择非单位步长循环的深度 | | `-tag-mem-space` | Tag memory space identifier for copy generation (default: 0) | 用于生成拷贝的 tag(标记)内存空间标识符(默认:0) | ### -affine-expand-index-ops **EN:** Lower affine operations operating on indices into more fundamental operations **中文:** 将作用于 index 的 affine op 降低为更基础的 op ### -affine-expand-index-ops-as-affine **EN:** Lower affine operations operating on indices into affine.apply operations **中文:** 将作用于 index 的 affine op 降低为 `affine.apply` op ### -affine-fold-memref-alias-ops **EN:** Fold memref alias ops into affine memory ops **中文:** 将 memref 别名 op 折叠进 affine 内存 op **EN:** The pass folds memref.subview, memref.expand_shape, and memref.collapse_shape operations into affine memory operations (currently only affine.load and affine.store ). This is similar to the fold-memrefalias-ops pass in the memref dialect but adds handling specific to affine operations. **中文:** 该 pass 将 `memref.subview`、`memref.expand_shape` 和 `memref.collapse_shape` op 折叠为 affine 内存 op(目前仅支持 `affine.load` 与 `affine.store`)。这与 memref 方言中的 `fold-memrefalias-ops` pass 类似,但增加了针对 affine op 的处理。 ### -affine-loop-coalescing **EN:** Coalesce nested loops with independent bounds into a single loop **中文:** 将边界相互独立的嵌套循环合并为单个循环 ### -affine-loop-fusion **EN:** Fuse affine loop nests **中文:** 融合 affine 循环嵌套 **EN:** This pass performs fusion of loop nests using a slicing-based approach. The transformation works on an MLIR Block granularity and applies to all blocks of the pass is run on. It combines two fusion strategies: producer-consumer fusion and sibling fusion. Producer-consumer fusion is aimed at fusing pairs of loops where the first one writes to a memref that the second reads. Sibling fusion targets pairs of loops that share no dependences between them but that load from the same memref. The fused loop nests, when possible, are rewritten to access significantly smaller local buffers instead of the original memref's, and the latter are often either completely optimized away or contracted. This transformation leads to enhanced locality and lower memory footprint through the elimination or contraction of temporaries/intermediate memref's. These benefits are sometimes achieved at the expense of redundant computation through a cost model that evaluates available choices such as the depth at which a source slice should be materialized in the designation slice. **中文:** 该 pass 使用基于切片(slicing)的方法对循环嵌套进行融合。变换以 MLIR Block 为粒度,作用于 pass 所处理的所有 block。它结合了两种融合策略:生产者-消费者融合(producer-consumer fusion)与兄弟融合(sibling fusion)。生产者-消费者融合的目标是融合成对的循环——第一个循环写入某个 memref,第二个循环读取该 memref。兄弟融合针对的是彼此之间没有依赖、但都从同一个 memref 加载数据的成对循环。当可能时,融合后的循环嵌套会被改写为访问显著更小的局部缓冲区(local buffer),而非原始的 memref;原始 memref 往往被完全优化掉或收缩。这种变换通过消除或收缩临时/中间 memref 来提升局部性并降低内存占用。这些收益有时是以冗余计算为代价的——通过一个 cost model(代价模型)来评估可选方案,例如在指定切片中应把源切片物化到哪个深度。 **Example 1 / 示例 1(Producer-consumer fusion):** ```mlir Input: func.func @producer_consumer_fusion(%arg0: memref<10xf32>, %arg1: memref<10xf32>) { %0 = memref.alloc() : memref<10xf32> %1 = memref.alloc() : memref<10xf32> %cst = arith.constant 0.000000e+00 : f32 affine.for %arg2 = 0 to 10 { affine.store %cst, %0[%arg2] : memref<10xf32> affine.store %cst, %1[%arg2] : memref<10xf32> } affine.for %arg2 = 0 to 10 { %2 = affine.load %0[%arg2] : memref<10xf32> %3 = arith.addf %2, %2 : f32 affine.store %3, %arg0[%arg2] : memref<10xf32> } affine.for %arg2 = 0 to 10 { %2 = affine.load %1[%arg2] : memref<10xf32> %3 = arith.mulf %2, %2 : f32 affine.store %3, %arg1[%arg2] : memref<10xf32> } return } Output: func.func @producer_consumer_fusion(%arg0: memref<10xf32>, %arg1: memref<10xf32>) { %0 = memref.alloc() : memref<1xf32> %1 = memref.alloc() : memref<1xf32> %cst = arith.constant 0.000000e+00 : f32 affine.for %arg2 = 0 to 10 { affine.store %cst, %0[0] : memref<1xf32> affine.store %cst, %1[0] : memref<1xf32> %2 = affine.load %1[0] : memref<1xf32> %3 = arith.mulf %2, %2 : f32 affine.store %3, %arg1[%arg2] : memref<10xf32> %4 = affine.load %0[0] : memref<1xf32> %5 = arith.addf %4, %4 : f32 affine.store %5, %arg0[%arg2] : memref<10xf32> } return } ``` **Example 2 / 示例 2(Sibling fusion):** ```mlir Input: func.func @sibling_fusion(%arg0: memref<10x10xf32>, %arg1: memref<10x10xf32>, %arg2: memref<10x10xf32>, %arg3: memref<10x10xf32>, %arg4: memref<10x10xf32>) { affine.for %arg5 = 0 to 3 { affine.for %arg6 = 0 to 3 { %0 = affine.load %arg0[%arg5, %arg6] : memref<10x10xf32> %1 = affine.load %arg1[%arg5, %arg6] : memref<10x10xf32> %2 = arith.mulf %0, %1 : f32 affine.store %2, %arg3[%arg5, %arg6] : memref<10x10xf32> } } affine.for %arg5 = 0 to 3 { affine.for %arg6 = 0 to 3 { %0 = affine.load %arg0[%arg5, %arg6] : memref<10x10xf32> %1 = affine.load %arg2[%arg5, %arg6] : memref<10x10xf32> %2 = arith.addf %0, %1 : f32 affine.store %2, %arg4[%arg5, %arg6] : memref<10x10xf32> } } return } Output: func.func @sibling_fusion(%arg0: memref<10x10xf32>, %arg1: memref<10x10xf32>, %arg2: memref<10x10xf32>, %arg3: memref<10x10xf32>, %arg4: memref<10x10xf32>) { affine.for %arg5 = 0 to 3 { affine.for %arg6 = 0 to 3 { %0 = affine.load %arg0[%arg5, %arg6] : memref<10x10xf32> %1 = affine.load %arg1[%arg5, %arg6] : memref<10x10xf32> %2 = arith.mulf %0, %1 : f32 affine.store %2, %arg3[%arg5, %arg6] : memref<10x10xf32> %3 = affine.load %arg0[%arg5, %arg6] : memref<10x10xf32> %4 = affine.load %arg2[%arg5, %arg6] : memref<10x10xf32> %5 = arith.addf %3, %4 : f32 affine.store %5, %arg4[%arg5, %arg6] : memref<10x10xf32> } } return } ``` **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-compute-tolerance` | Fractional increase in additional computation tolerated while fusing | 融合时允许额外计算量的分数比例增长 | | `-fast-mem-space` | Faster memory space number to promote fusion buffers to | 用于将融合缓冲区提升到的更快内存空间编号 | | `-local-buf-threshold` | Threshold size (KiB) for promoting local buffers to fast memory space | 将局部缓冲区提升到快速内存空间的阈值大小(KiB) | | `-maximal` | Enables maximal loop fusion | 启用最大循环融合 | | `-mode` | fusion mode to attempt | 要尝试的融合模式 | ### -affine-loop-invariant-code-motion **EN:** Hoist loop invariant instructions outside of affine loops **中文:** 将循环不变(loop invariant)指令提升到 affine 循环之外 ### -affine-loop-normalize **EN:** Apply normalization transformations to affine loop-like ops **中文:** 对形似 affine 循环的 op 应用规范化变换 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-promote-single-iter` | Promote single iteration loops | 提升单迭代循环 | | `-use-expensive-math` | Use Presburger arithmetic to constantize loop upper bounds (higher analysis cost) | 使用 Presburger 算术将循环上界常量化(分析代价更高) | ### -affine-loop-tile **EN:** Tile affine loop nests **中文:** 对 affine 循环嵌套进行分块(tiling) **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-cache-size` | Set size of cache to tile for in KiB (default: 512) | 设置用于分块的缓存大小(单位 KiB)(默认:512) | | `-separate` | Separate full and partial tiles (default: false) | 分离完整块与部分块(默认:false) | | `-tile-size` | Use this tile size for all loops | 对所有循环使用此分块大小 | | `-tile-sizes` | List of tile sizes for each perfect nest (overridden by -tile-size) | 每个完美嵌套的分块大小列表(被 `-tile-size` 覆盖) | ### -affine-loop-unroll **EN:** Unroll affine loops **中文:** 展开 affine 循环 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-unroll-factor` | Use this unroll factor for all loops being unrolled, set it to -1, and it will fully unroll. | 对所有待展开的循环使用此展开因子;设为 -1 时完全展开。 | | `-unroll-up-to-factor` | Allow unrolling up to the factor specified | 允许最多展开到指定因子 | | `-unroll-num-reps` | Unroll innermost loops repeatedly this many times | 最内层循环重复展开的次数 | | `-unroll-full-threshold` | Unroll all loops with trip count less than or equal to this | 完全展开所有迭代次数小于或等于该值的循环 | | `-cleanup-unroll` | Fully unroll the cleanup loop when possible. | 在可能时完全展开清理(cleanup)循环。 | ### -affine-loop-unroll-jam **EN:** Unroll and jam affine loops **中文:** 对 affine 循环进行展开并压缩(unroll-and-jam) **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-unroll-jam-factor` | Use this unroll jam factor for all loops (default 4) | 对所有循环使用此展开-压缩因子(默认 4) | ### -affine-parallelize **EN:** Convert affine.for ops into 1-D affine.parallel **中文:** 将 `affine.for` op 转换为 1 维的 `affine.parallel` **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-max-nested` | Maximum number of nested parallel loops to produce. Defaults to unlimited (UINT_MAX). | 生成的嵌套并行循环的最大层数。默认无限制(UINT_MAX)。 | | `-parallel-reductions` | Whether to parallelize reduction loops. Defaults to false. | 是否对规约(reduction)循环进行并行化。默认 false。 | ### -affine-pipeline-data-transfer **EN:** Pipeline non-blocking data transfers between explicitly managed levels of the memory hierarchy **中文:** 在显式管理的内存层次结构各层之间流水线化非阻塞数据传输 **EN:** This pass performs a transformation to overlap non-blocking DMA operations in a loop with computations through double buffering. This is achieved by advancing dma_start operations with respect to other operations. **中文:** 该 pass 执行一种变换,通过双缓冲(double buffering)使循环中的非阻塞 DMA 操作与计算重叠。这通过将 `dma_start` op 相对于其他 op 提前来实现。 ```mlir Input func.func @pipelinedatatransfer() { %0 = memref.alloc() : memref<256xf32> %1 = memref.alloc() : memref<32xf32, 1> %2 = memref.alloc() : memref<1xf32> %c0 = arith.constant 0 : index %c128 = arith.constant 128 : index affine.for %i0 = 0 to 8 { affine.dma_start %0[%i0], %1[%i0], %2[%c0], %c128 : memref<256xf32>, memref<32xf32, 1>, memref<1xf32> affine.dma_wait %2[%c0], %c128 : memref<1xf32> %3 = affine.load %1[%i0] : memref<32xf32, 1> %4 = "compute"(%3) : (f32) -> f32 affine.store %4, %1[%i0] : memref<32xf32, 1> } return } Output module { func.func @pipelinedatatransfer() { %c8 = arith.constant 8 : index %c0 = arith.constant 0 : index %0 = memref.alloc() : memref<256xf32> %c0_0 = arith.constant 0 : index %c128 = arith.constant 128 : index %1 = memref.alloc() : memref<2x32xf32, 1> %2 = memref.alloc() : memref<2x1xf32> affine.dma_start %0[%c0], %1[%c0 mod 2, %c0], %2[%c0 mod 2, symbol(%c0_0)], %c128 : memref<256xf32>, memref<2x32xf32, 1>, memref<2x1xf32> affine.for %arg0 = 1 to 8 { affine.dma_start %0[%arg0], %1[%arg0 mod 2, %arg0], %2[%arg0 mod 2, symbol(%c0_0)], %c128 : memref<256xf32>, memref<2x32xf32, 1>, memref<2x1xf32> %8 = affine.apply #map3(%arg0) %9 = affine.apply #map4(%8) %10 = affine.apply #map4(%8) affine.dma_wait %2[%8 mod 2, symbol(%c0_0)], %c128 : memref<2x1xf32> %11 = affine.load %1[%8 mod 2, %8] : memref<2x32xf32, 1> %12 = "compute"(%11) : (f32) -> f32 affine.store %12, %1[%8 mod 2, %8] : memref<2x32xf32, 1> } %3 = affine.apply #map3(%c8) %4 = affine.apply #map4(%3) %5 = affine.apply #map4(%3) affine.dma_wait %2[%3 mod 2, symbol(%c0_0)], %c128 : memref<2x1xf32> %6 = affine.load %1[%3 mod 2, %3] : memref<2x32xf32, 1> %7 = "compute"(%6) : (f32) -> f32 affine.store %7, %1[%3 mod 2, %3] : memref<2x32xf32, 1> memref.dealloc %2 : memref<2x1xf32> memref.dealloc %1 : memref<2x32xf32, 1> return } } ``` --- ### -affine-raise-from-memref **EN:** Turn some memref operators to affine operators where supported **中文:** 在受支持的情况下,将一些 memref 算子转换为 affine 算子。 **EN:** Raise memref.load and memref.store to affine.store and affine.load, inferring the affine map of those operators if needed. This allows passes like –affine-scalrep to optimize those loads and stores (forwarding them or eliminating them). They can be turned back to memref dialect ops with –lower-affine. **中文:** 将 memref.load 和 memref.store 提升(raise)为 affine.store 和 affine.load,并在需要时推断这些算子的 affine map。这使得诸如 `–affine-scalrep` 等 pass 能够优化这些 load 和 store(转发或消除它们)。之后可以用 `–lower-affine` 将它们转回 memref 方言的 op。 ### -affine-scalrep **EN:** Replace affine memref accesses by scalars by forwarding stores to loads and eliminating redundant loads **中文:** 通过将 store 转发到 load 并消除冗余 load,用标量替换(replace)affine 的 memref 访问。 **EN:** This pass performs store to load forwarding and redundant load elimination for affine memref accesses and potentially eliminates the entire memref if all its accesses are forwarded. **中文:** 该 pass 对 affine 的 memref 访问执行 store-to-load 转发(store to load forwarding)和冗余 load 消除(redundant load elimination),如果某个 memref 的所有访问都被转发,则可能将其整个消除。 **Input / 输入:** ```mlir func.func @store_load_affine_apply() -> memref<10x10xf32> { %cf7 = arith.constant 7.0 : f32 %m = memref.alloc() : memref<10x10xf32> affine.for %i0 = 0 to 10 { affine.for %i1 = 0 to 10 { affine.store %cf7, %m[%i0, %i1] : memref<10x10xf32> %v0 = affine.load %m[%i0, %i1] : memref<10x10xf32> %v1 = arith.addf %v0, %v0 : f32 } } return %m : memref<10x10xf32> } ``` **Output / 输出:** ```mlir module { func.func @store_load_affine_apply() -> memref<10x10xf32> { %cst = arith.constant 7.000000e+00 : f32 %0 = memref.alloc() : memref<10x10xf32> affine.for %arg0 = 0 to 10 { affine.for %arg1 = 0 to 10 { affine.store %cst, %0[%arg0, %arg1] : memref<10x10xf32> %1 = arith.addf %cst, %cst : f32 } } return %0 : memref<10x10xf32> } } ``` ### -affine-simplify-min-max **EN:** Simplify affine min/max/apply **中文:** 简化 affine 的 min/max/apply。 **EN:** Apply the SimplifyAffineMaxOp, SimplifyAffineMinOp and SimplifyAffineApplyOp patterns in addition to AffineMin/Max canonicalization patterns until a fixed point is reached. These patterns apply ValueBoundsOp interface on AffineMin/Max ops and additional simplifications such as: `min(x, y, cst) / cst -> 1` when x, y, cst are all >= 0. This is typically useful to extract more static information from IR after tiling but can also come at a cost due to Presburger-style analysis. **中文:** 除了 AffineMin/Max 的 canonicalization(规范化)模式外,还应用 SimplifyAffineMaxOp、SimplifyAffineMinOp 和 SimplifyAffineApplyOp 模式,直到达到不动点(fixed point)。这些模式对 AffineMin/Max op 应用 ValueBoundsOp interface,并做额外的简化,例如:`min(x, y, cst) / cst -> 1`,其中 x、y、cst 都 >= 0。这通常用于在 tiling 之后从 IR 中提取更多静态信息(static information),但由于 Presburger 风格分析也可能带来开销。 ### -affine-simplify-structures **EN:** Simplify affine expressions in maps/sets and normalize memrefs **中文:** 简化 map/set 中的 affine 表达式,并规范化(normalize)memref。 ### -affine-simplify-with-bounds **EN:** Simplify affine index operations using value bounds analysis **中文:** 使用值域分析(value bounds analysis)简化 affine 索引操作。 **EN:** This pass simplifies affine.delinearize_index / affine.linearize_index pairs and affine.for by using value bounds analysis to match basis products. Unlike the built-in canonicalization patterns which only use exact OpFoldResult comparisons, this pass can prove equality of dynamic basis products through ValueBoundsConstraintSet. **中文:** 该 pass 通过使用值域分析来匹配基积(basis products),从而简化 affine.delinearize_index / affine.linearize_index 配对以及 affine.for。与仅使用精确 OpFoldResult 比较的内置 canonicalization 模式不同,该 pass 能够通过 ValueBoundsConstraintSet 证明动态基积(dynamic basis products)相等。 ### -affine-super-vectorize **EN:** Vectorize to a target independent n-D vector abstraction **中文:** 向量化到一个与目标无关(target independent)的 n 维向量抽象。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-virtual-vector-size` | Specify an n-D virtual vector size for vectorization. This must be greater than zero. | 指定用于向量化(vectorization)的 n 维虚拟向量大小。该值必须大于零。 | | `-test-fastest-varying` | Specify a 1-D, 2-D or 3-D pattern of fastest varying memory dimensions to match. See defaultPatterns in Vectorize.cpp for a description and examples. This is used for testing purposes | 指定要匹配的、变化最快(fastest varying)的内存维度的 1 维、2 维或 3 维模式。描述与示例见 Vectorize.cpp 中的 defaultPatterns。此选项用于测试目的。 | | `-vectorize-reductions` | Vectorize known reductions expressed via iter_args. Switched off by default. | 向量化通过 iter_args 表达的已知归约(reduction)。默认关闭。 | --- ## 'amdgpu' Dialect Passes('amdgpu' 方言 Pass) ### -amdgpu-emulate-atomics **EN:** Emulate atomic operations on chipsets that do not support them **中文:** 在不支持原子操作的芯片组(chipset)上模拟原子操作 **EN:** This pass rewrites any AMDGPU-specific atomic operation that is not supported on the given chipset into a compare-and-swap loop. **中文:** 该 Pass 会将任何在给定芯片组(chipset)上不受支持的 AMDGPU 专用原子操作重写为 compare-and-swap(比较并交换)循环。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-chipset` | Chipset that these operations will run on | 这些操作将要运行的芯片组(chipset) | ### -amdgpu-maskedload-to-load **EN:** Lower the operations from the vector maskedload to vector load **中文:** 将向量 maskedload 操作降低(lower)为向量 load **EN:** This pass creates a transfer read op lowering optimization. The lowering will produce a conditional check at runtime. If within bounds, a vector trasfer read op will be lowered to a combination of vector.load, arith.select and vector.broadcast. If not, it will fallback to the default lowering of the transfer_read op. **中文:** 该 Pass 创建一个 transfer read(转移读)op 的降低(lowering)优化。该降低会在运行时产生一个条件检查:若访问在边界之内,vector transfer read op 将被降低为 vector.load、arith.select 与 vector.broadcast 的组合;否则将回退到 transfer_read op 的默认降低方式。 **EN:** This pattern will make it possible for masked transfer_read to be lowered towards buffer load with bounds check, allowing a more optimized global load accessing pattern compared with existing implementation of llvm.intr.masked.load on vectors. **中文:** 该模式(pattern)将使带掩码的 transfer_read 能够被降低为带边界检查的 buffer load,从而与现有针对向量的 llvm.intr.masked.load 实现相比,得到更优化的全局内存访问模式。 ### -amdgpu-resolve-strided-metadata **EN:** Resolve memref.extract_strided_metadata on AMDGPU ops **中文:** 在 AMDGPU op 上解析(resolve)memref.extract_strided_metadata **EN:** This pass rrewrites memref.extract_strided_metadata operations targeting the AMDGPU dialect casts. The patterns in this pass should normally be run alongside those in -expand-strided-metadata, and creating a pass that combines those two sets of patterns is the recommended way to use this functionality. However, this pass (which will likely need a second -expand-strided-metadata after it) is provided so that simple usecases do not need to create custom passes. These patterns have not been added to -expnad-strided-metadata to prevent the memref dialect from depending on platform-specific code. **中文:** 该 Pass 重写那些以 AMDGPU 方言 cast(转换)为目标的 memref.extract_strided_metadata 操作。本 Pass 中的模式通常应与 -expand-strided-metadata 中的模式一起运行,而创建一个组合这两组模式的 pass 是推荐使用此功能的方式。不过,提供本 Pass(其后很可能还需要再执行一次 -expand-strided-metadata),是为了让简单的用例无需创建自定义 pass。这些模式没有被加入 -expnad-strided-metadata,以避免 memref 方言依赖平台特定代码。 --- ## 'arith' Dialect Passes('arith' 方言 Pass) ### -arith-emulate-unsupported-floats **EN:** Emulate operations on unsupported floats with extf/truncf Emulate arith and vector floating point operations that use float types which are unspported on a target by inserting extf/truncf pairs around all such operations in order to produce arithmetic that can be performed while preserving the original rounding behavior. This pass does not attempt to reason about the operations being performed to determine when type conversions can be elided. **中文:** 使用 extf/truncf 模拟对不受支持浮点类型的运算。通过在目标硬件不支持(unspported)的浮点类型上的所有此类 arith 与 vector 浮点运算周围插入 extf/truncf 对,来生成可执行的算术,同时保留原始的舍入行为(rounding behavior)。本 Pass 不会尝试推理所执行的运算以判断何时可以省略类型转换。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-source-types` | MLIR types without arithmetic support on a given target | 在给定目标上不受算术支持的 MLIR 类型 | | `-target-type` | MLIR type to convert the unsupported source types to | 用于将不支持的源类型转换到的 MLIR 类型 | ### -arith-emulate-wide-int **EN:** Emulate 2*N-bit integer operations using N-bit operations Emulate arith integer operations that use too wide integer types with equivalent operations on supported narrow integer types. This is done by splitting original integer values into two halves. This pass is intended preserve semantics but not necessarily provide the most efficient implementation. TODO: Optimize op emulation. Currently, only power-of-two integer bitwidths are supported. **中文:** 使用 N 位运算来模拟 2*N 位整数运算。通过将原始整数值拆分为两半,用受支持的窄整数类型上的等价运算来模拟那些使用了过宽整数类型的 arith 整数运算。本 Pass 旨在保留语义,但不一定提供最高效的实现。TODO(待办):优化 op 的模拟。目前仅支持 2 的幂次整数位宽。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-widest-int-supported` | Widest integer type supported by the target | 目标所支持的最宽整数类型 | ### -arith-expand **EN:** Legalize Arith ops to be convertible to LLVM. **中文:** 将 Arith op 合法化,使其可转换为 LLVM。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-include-bf16` | Enable the BF16 expansion patterns | 启用 BF16 展开模式(expansion patterns) | | `-include-f8e8m0` | Enable the F8E8M0 expansion patterns | 启用 F8E8M0 展开模式 | | `-include-f4e2m1` | Enable the F4E2M1 expansion patterns | 启用 F4E2M1 展开模式 | | `-include-flush-denormals` | Enable expansion of `arith.flush_denormals` on IEEE-like floating-point types | 在类 IEEE 浮点类型上启用对 `arith.flush_denormals` 的展开 | | `-include-min-max-f` | Enable expansion of the floating-point min/max ops (maximumf/minimumf/maxnumf/minnumf). These ops also have a direct arith-to-llvm lowering to the `llvm.intr.maximum/minimum/maxnum/minnum` intrinsics; disable this so pipelines that run arith-to-llvm can use those single-instruction lowerings instead of the cmpf/select expansion | 启用浮点 min/max op(maximumf/minimumf/maxnumf/minnumf)的展开。这些 op 也有直接的 arith-to-llvm lowering,对应到 `llvm.intr.maximum/minimum/maxnum/minnum` intrinsics;禁用此选项以便运行 arith-to-llvm 的 pipeline 可以使用那些单指令 lowering,而非 cmpf/select 展开 | | `-include-min-max-i` | Enable expansion of the signed/unsigned integer min/max ops (maxsi/maxui/minsi/minui). These ops also have a direct arith-to-llvm lowering to the `llvm.intr.smax/umax/smin/umin` intrinsics; disable this so pipelines that run arith-tollvm can use those single-instruction lowerings instead of the cmpi/select expansion | 启用有符号/无符号整数 min/max op(maxsi/maxui/minsi/minui)的展开。这些 op 也有直接的 arith-to-llvm lowering,对应到 `llvm.intr.smax/umax/smin/umin` intrinsics;禁用此选项以便运行 arith-tollvm 的 pipeline 可以使用那些单指令 lowering,而非 cmpi/select 展开 | ### -arith-int-range-narrowing **EN:** Reduce integer operations bitwidth based on integer range analysis This pass runs integer range analysis and tries to narrow arith ops to the specified bitwidth based on its results. bitwidthsSupported assumed to be not wider than index type. TODO: get index width from DLTI. **中文:** 基于整数范围分析(integer range analysis)降低整数运算的位宽。本 Pass 运行整数范围分析,并根据其结果尝试将 arith op 收窄到指定的位宽。bitwidthsSupported 假定不会比 index 类型更宽。TODO(待办):从 DLTI 获取 index 宽度。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-int-bitwidths-supported` | Integer bitwidths supported | 支持的整数位宽 | ### -arith-unsigned-when-equivalent **EN:** Replace signed ops with unsigned ones where they are proven equivalent **中文:** 在证明等价时,用无符号 op 替换有符号 op。 **EN:** Replace signed ops with their unsigned equivalents when integer range analysis determines that their arguments and results are all guaranteed to be non-negative when interpreted as signed integers. When this occurs, we know that the semantics of the signed and unsigned operations are the same, since they share the same behavior when their operands and results are in the range [0, signed_max(type)]. The affect ops include division, remainder, shifts, min, max, and integer comparisons. **中文:** 当整数范围分析判定其参数与结果在被解释为有符号整数时都保证为非负时,将有符号 op 替换为其无符号等价物。此时我们知道有符号与无符号运算的语义相同,因为当它们的操作数与结果落在区间 [0, signed_max(type)] 内时行为一致。受影响的 op(affect ops)包括除法、取余、移位、min、max 以及整数比较。 ### -int-range-optimizations **EN:** Do optimizations based on integer range analysis This pass runs integer range analysis and apllies optimizations based on its results. It replaces operations with known-constant results with said constants, rewrites (0 <= %x < D) mod D to %x . **中文:** 基于整数范围分析进行优化。本 Pass 运行整数范围分析,并根据其结果应用(applies)优化。它将具有已知常量结果的运算替换为该常量,并将 (0 <= %x < D) mod D 重写为 %x 。 --- ## 'arm_sme' Dialect Passes('arm_sme' 方言 Pass) ### -arm-sme-outer-product-fusion **EN:** Fuse ‘arm_sme.outerproduct’ operations into 2-way or 4-way widening variants **中文:** 将 ‘arm_sme.outerproduct’ op 融合为 2-way(双路)或 4-way(四路)widening(扩展精度)变体。 **EN:** This pass fuses ‘arm_sme.outerproduct’ operations that are chained via the accumulator into 2-way or 4-way ArmSME outer product operations. **中文:** 该 pass 将经由累加器(accumulator)串联的 ‘arm_sme.outerproduct’ op 融合为 2-way 或 4-way 的 ArmSME 外积(outer product)操作。 **For example / 例如:** ```mlir %a0_ext = arith.extf %a0 : vector<[4]xf16> to vector<[4]xf32> %b0_ext = arith.extf %b0 : vector<[4]xf16> to vector<[4]xf32> %a1_ext = arith.extf %a1 : vector<[4]xf16> to vector<[4]xf32> %b1_ext = arith.extf %b1 : vector<[4]xf16> to vector<[4]xf32> %0 = arm_sme.outerproduct %a0_ext, %b0_ext : vector<[4]xf32>, vector<[4]xf32> %1 = arm_sme.outerproduct %a1_ext, %b1_ext acc(%0) : vector<[4]xf32>, vector<[4]xf32> Becomes: %a_packed = vector.interleave %a0, %a1 : vector<[4]xf16> -> vector<[8]xf16> %b_packed = vector.interleave %b0, %b1 : vector<[4]xf16> -> vector<[8]xf16> %0 = arm_sme.fmopa_2way %a_packed, %b_packed : vector<[8]xf16>, vector<[8]xf16> into vector<[4]x[4]xf32> ``` **EN:** For further information on the 2-way or 4-way widening ops see: https://mlir.llvm.org/docs/Dialects/ArmSME/#arm_smefmopa_2way-arm_smefmopa_2wayop https://mlir.llvm.org/docs/Dialects/ArmSME/#arm_smesmopa_4way-arm_smesmopa_4wayop **中文:** 关于 2-way 或 4-way widening(扩展精度)操作的更多信息,参见: https://mlir.llvm.org/docs/Dialects/ArmSME/#arm_smefmopa_2way-arm_smefmopa_2wayop https://mlir.llvm.org/docs/Dialects/ArmSME/#arm_smesmopa_4way-arm_smesmopa_4wayop ### -arm-sme-vector-legalization **EN:** Legalize vectors for ArmSME **中文:** 为 ArmSME 对 vector(向量)进行合法化(legalize)。 **EN:** This pass legalizes vector operations so that they can be lowered to ArmSME. This includes decomposing operations that operate on vector types larger than a single SME tile (e.g. vector<[8]x[8]xf32>) into multiple SME tile-sized operations, as well as rewrites needed to get operations into forms compatible with SME lowerings. **中文:** 该 pass 对 vector 操作进行合法化(legalize),使其能够被降级(lower)到 ArmSME。这包括将作用于大于单个 SME tile 的 vector 类型(如 vector<[8]x[8]xf32>)的操作分解为多个 SME tile 大小的操作,以及将操作改写为与 SME 降级兼容形式所需的变换。 **EN:** Note: Decomposition is currently limited to vector types that are an exact multiple of SME tiles. That is scalable in two dimensions, with both the rows and columns divisible by the SVE vector length for the element type. **中文:** 注意(Note):分解目前仅限于恰好为 SME tile 整数倍的 vector 类型。即该 vector 在两个维度上均可扩展(scalable),且行数和列数都能被该元素类型的 SVE vector 长度整除。 ### -enable-arm-streaming **EN:** Enable Armv9 Streaming SVE mode **中文:** 启用 Armv9 Streaming SVE(流式)模式。 **EN:** Enables the Armv9 Streaming SVE mode [1] for func.func ops by annotating them with attributes. See options for more details. **中文:** 通过为 func.func op 添加属性(annotation)的方式,为其启用 Armv9 Streaming SVE(流式)模式 [1]。更多细节参见选项(Options)。 **EN:** [1] https://developer.arm.com/documentation/ddi0616/aa **中文:** [1] https://developer.arm.com/documentation/ddi0616/aa **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-streaming-mode` | Select how streaming-mode is managed at the function-level. | 选择在函数层面如何管理 streaming-mode(流式模式)。 | | `-za-mode` | Select how ZA-storage is managed at the function-level. | 选择在函数层面如何管理 ZA-storage(ZA 存储)。 | | `-if-required-by-ops` | Only apply the selected streaming/ZA modes if the function contains ops that implement the ArmSMETileOpInterface. | 仅当函数包含实现了 ArmSMETileOpInterface 的 op 时,才应用所选的 streaming/ZA 模式。 | | `-if-scalable-and-supported` | Only apply the selected streaming/ZA modes if the function contains supported scalable vector operations. | 仅当函数包含受支持的 scalable(可扩展)vector 操作时,才应用所选的 streaming/ZA 模式。 | ### -test-arm-sme-tile-allocation **EN:** Tests SME ‘virtual tile’ allocation **中文:** 测试 SME ‘virtual tile’(虚拟 tile)分配。 **EN:** This pass does tile allocation for SME “virtual tiles”. It is run at the ‘func.func’ op level, and assigns tile IDs (via an attribute) to all ops that implement the ArmSMETileOpInterface. Note: This pass is only intended to be used for testing, tile allocation is done as part of the ArmSME to LLVM conversion (convert-arm-sme-to-llvm). **中文:** 该 pass 为 SME “virtual tiles”(虚拟 tile)执行 tile 分配。它在 ‘func.func’ op 层级运行,并通过属性(attribute)为所有实现了 ArmSMETileOpInterface 的 op 分配 tile ID。注意(Note):该 pass 仅用于测试;tile 分配是作为 ArmSME 到 LLVM 转换(convert-arm-sme-to-llvm)的一部分完成的。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-dump-tile-live-ranges` | Dump the live ranges of SME tiles (for debugging) | 转储 SME tile 的活跃区间(live range)(用于调试)。 | | `-preprocess-only` | Only preprocess IR so it is ready for tile allocation (but do not allocate any tiles) | 仅对 IR 做预处理使其就绪以便进行 tile 分配(但不实际分配任何 tile)。 | --- ## ‘arm_sve’ Dialect Passes('arm_sve' 方言 Pass) ### -arm-sve-legalize-vector-storage **EN:** Ensures stores of SVE vector types will be legal **中文:** 确保对 SVE 向量类型的存储(store)是合法的。 **EN:** This pass ensures that loads, stores, and allocations of SVE vector types will be legal in the LLVM backend. It does this at the memref level, so this pass must be applied before lowering all the way to LLVM. This pass currently addresses two issues. **中文:** 该 Pass 确保对 SVE 向量类型的加载(load)、存储(store)与分配(allocation)在 LLVM 后端中是合法的。它在 memref 层面完成这一点,因此必须在完全降级到 LLVM 之前应用本 Pass。本 Pass 目前处理两个问题。 **Loading and storing predicate types / 加载与存储谓词类型:** **EN:** It is only legal to load/store predicate types equal to (or greater than) a full predicate register, which in MLIR is `vector<[16]xi1>`. Smaller predicate types (`vector<[1|2|4|8]xi1>`) must be converted to/from a full predicate type (referred to as a svbool) before and after storing and loading respectively. This pass does this by widening allocations and inserting conversion intrinsics. Note: Non-powers-of-two masks (e.g. `vector<[7]xi1>`), which are not SVE predicates, are ignored. **中文:** 只有与完整谓词寄存器相等(或更大)的谓词类型才允许加载/存储,在 MLIR 中即 `vector<[16]xi1>`。更小的谓词类型(`vector<[1|2|4|8]xi1>`)必须在分别进行存储和加载之前、之后转换为完整的谓词类型(称为 svbool)。本 Pass 通过加宽分配并插入转换内建函数(intrinsic)来实现这一点。注意:非 2 的幂次数的掩码(例如 `vector<[7]xi1>`),它们不是 SVE 谓词,会被忽略。 **For example / 例如:** ```mlir %alloca = memref.alloca() : memref> %mask = vector.constant_mask [4] : vector<[4]xi1> memref.store %mask, %alloca[] : memref> %reload = memref.load %alloca[] : memref> ``` **Becomes / 变为:** ```mlir %alloca = memref.alloca() {alignment = 1 : i64} : memref> %mask = vector.constant_mask [4] : vector<[4]xi1> %svbool = arm_sve.convert_to_svbool %mask : vector<[4]xi1> memref.store %svbool, %alloca[] : memref> %reload_svbool = memref.load %alloca[] : memref> %reload = arm_sve.convert_from_svbool %reload_svbool : vector<[4]xi1> ``` **Relax alignments for SVE vector allocas / 放宽 SVE 向量 alloca 的对齐:** **EN:** The storage for SVE vector types only needs to have an alignment that matches the element type (for example 4 byte alignment for f32s). However, the LLVM backend currently defaults to aligning to base size x element size bytes. For non-legal vector types like `vector<[8]xf32>` this results in 8 x 4 = 32-byte alignment, but the backend only supports up to 16-byte alignment for SVE vectors on the stack. Explicitly setting a smaller alignment prevents this issue. **中文:** SVE 向量类型的存储只需要具有与元素类型匹配的对齐(例如对 f32s 采用 4 字节对齐)。然而,LLVM 后端当前默认按「基数大小 × 元素大小」的字节数进行对齐。对于像 `vector<[8]xf32>` 这样不合法的向量类型,这会导致 8 x 4 = 32 字节的对齐,但后端对栈上的 SVE 向量最多只支持 16 字节对齐。显式设置更小的对齐可避免此问题。 --- ## ‘async’ Dialect Passes(‘async’ 方言 Pass) ### -async-func-to-async-runtime **EN:** Lower async.func operations to the explicit async.runtime and async.coro operations **中文:** 将 async.func 操作降级为显式的 async.runtime 和 async.coro 操作。 ### -async-parallel-for **EN:** Convert scf.parallel operations to multiple async compute ops executed concurrently for non-overlapping iteration ranges **中文:** 将 scf.parallel 操作转换为多个并发执行的 async compute(异步计算)op,用于不重叠的迭代范围。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-async-dispatch` | Dispatch async compute tasks using recursive work splitting. If `false` async compute tasks will be launched using simple for loop in the caller thread. | 使用递归任务切分来分发 async compute(异步计算)任务。若为 `false`,则会在调用者线程中用简单的 for 循环启动这些 async compute 任务。 | | `-num-workers` | The number of available workers to execute async operations. If `-1` the value will be retrieved from the runtime. | 用于执行异步操作的可用 worker(工作线程)数量。若为 `-1`,该值将从运行时获取。 | | `-min-task-size` | The minimum task size for sharding parallel operation. | 对并行操作进行分片时的最小任务大小。 | ### -async-runtime-policy-based-ref-counting **EN:** Policy based reference counting for Async runtime operations **中文:** 针对 Async(异步)运行时操作的基于策略的引用计数。 **EN:** This pass works at the async runtime abtraction level, after all async.execute and async.await operations are lowered to the async runtime API calls, and async coroutine operations. **中文:** 本 pass 工作在 async 运行时抽象层,此时所有 async.execute 和 async.await 操作都已被降级为 async 运行时 API 调用以及 async 协程(coroutine)操作。 **EN:** This pass doesn’t rely on reference counted values liveness analysis, and instead uses simple policy to create reference counting operations. If the program violates any of the assumptions, then this pass might lead to memory leaks or runtime errors. **中文:** 本 pass 不依赖带引用计数值的活性分析(liveness analysis),而是使用简单的策略来创建引用计数操作。如果程序违反了其中任何一条假设,那么本 pass 可能会导致内存泄漏或运行时错误。 **EN:** The default reference counting policy assumptions: **中文:** 默认的引用计数策略假设如下: **EN:** 1. Async token can be awaited or added to the group only once. 2. Async value or group can be awaited only once. **中文:** 1. Async token(异步令牌)只能被 await(等待)一次,或被加入组一次。 2. Async value(异步值)或 group(组)只能被 await 一次。 **EN:** Under these assumptions reference counting only needs to drop reference: **中文:** 在这些假设下,引用计数只需在以下位置丢弃引用: **EN:** 1. After async.runtime.await operation for async tokens and groups (until error handling is not implemented for the sync await). 2. After async.runtime.is_error operation for async tokens and groups (this is the last operation in the coroutine resume function). 3. After async.runtime.load operation for async values. **中文:** 1. 在 async tokens(异步令牌)和 groups(组)的 async.runtime.await 操作之后(直到为 sync await 实现错误处理之前)。 2. 在 async tokens 和 groups 的 async.runtime.is_error 操作之后(这是协程恢复函数中的最后一个操作)。 3. 在 async values(异步值)的 async.runtime.load 操作之后。 **EN:** This pass introduces significanly less runtime overhead compared to the automatic reference counting. **中文:** 与自动引用计数相比,本 pass 引入了显著更少的运行时开销。 ### -async-runtime-ref-counting **EN:** Automatic reference counting for Async runtime operations **中文:** 针对 Async(异步)运行时操作的自动引用计数。 **EN:** This pass works at the async runtime abtraction level, after all async.execute and async.await operations are lowered to the async runtime API calls, and async coroutine operations. **中文:** 本 pass 工作在 async 运行时抽象层,此时所有 async.execute 和 async.await 操作都已被降级为 async 运行时 API 调用以及 async 协程(coroutine)操作。 **EN:** It relies on the LLVM coroutines switched-resume lowering semantics for the correct placing of the reference counting operations. **中文:** 它依赖 LLVM 协程(coroutines)的 switched-resume 降级语义来正确放置引用计数操作。 **EN:** See: https://llvm.org/docs/Coroutines.html#switched-resume-lowering **中文:** 参见:https://llvm.org/docs/Coroutines.html#switched-resume-lowering ### -async-runtime-ref-counting-opt **EN:** Optimize automatic reference counting operations for the Async runtime by removing redundant operations **中文:** 通过移除冗余操作来优化 Async(异步)运行时的自动引用计数操作。 ### -async-to-async-runtime **EN:** Lower all high level async operations (e.g. async.execute) to the explicit async.runtime and async.coro operations **中文:** 将所有高层 async(异步)操作(例如 async.execute)降级为显式的 async.runtime 和 async.coro 操作。 --- ## 'emitc' Dialect Passes('emitc' 方言 Pass) ### -form-expressions **EN:** Form C-style expressions from C-operator ops. The pass wraps emitc ops modelling C operators in emitc.expression ops and then folds single-use expressions into their users where possible. **中文:** 从 C 运算符 op(C-operator ops)构造 C 风格表达式。该 pass 将建模 C 运算符的 emitc op 包裹为 `emitc.expression` op,并在可能时将单使用(single-use)表达式折叠到其使用者中。 ### -mlgo-add-reflection-map **EN:** Add a reflection map and a helper method to EmitC classes for runtime field lookup. **中文:** 为 EmitC 类添加一个反射映射(reflection map)和一个辅助方法,用于运行时的字段查找。 **EN:** This pass adds a reflectionMap field and an accompanying getBufferForName method to EmitC classes, enabling runtime lookup of class fields by name. Each emitc.field is expected to have an attribute (configured by the included-field-attrs option) that is an array containing a single string attribute which will be used as the reflection map key. If none of the specified attributes are present on the field, the field will be excluded from the reflection map. **中文:** 该 pass 为 EmitC 类添加 `reflectionMap` 字段及配套的 `getBufferForName` 方法,支持按名称在运行时查找类的字段。每个 `emitc.field` 预期具有一个属性(由 `-included-field-attrs` 选项配置),该属性是一个仅包含单个字符串属性的数组,此字符串将用作反射映射的键。如果字段上不存在任何指定的属性,则该字段会被排除在反射映射之外。 **Example / 示例:** ```mlir emitc.class @MyClass { emitc.field @field0 : !emitc.array<1xf32> {emitc.field_ref = ["feature0"]} emitc.func @execute() { ... } } Becomes: emitc.class @MyClass { emitc.field @field0 : !emitc.array<1xf32> {emitc.field_ref = ["feature0"]} // reflectionMap maps the string "feature0" to the address of @field0 emitc.field @reflectionMap : const std::map = {{"feature0", &field0}} emitc.func @getBufferForName(%name: string) -> char* { return reflectionMap.at(%name) } emitc.func @execute() { ... } } ``` **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-included-field-attrs` | Attribute keys used to extract field names from a field's attribute dictionary | 用于从字段的属性字典中提取字段名的属性键 | ### -wrap-emitc-func-in-class **EN:** Wrap functions in classes, using arguments as fields. **中文:** 将函数包裹进类中,并以其参数作为字段。 **EN:** This pass transforms emitc.func operations into emitc.class operations. Function arguments become fields of the class, and the function body is moved to a new member method within the class. By default, this is operator()(). **中文:** 该 pass 将 `emitc.func` op 转换为 `emitc.class` op。函数参数成为类的字段,函数体被移入类内的一个新成员方法中;默认情况下该成员方法为 `operator()()`。 **EN:** If the corresponding function argument has attributes (accessed via argAttrs), these attributes are attached to the field operation. Otherwise, the field is created without additional attributes. **中文:** 如果对应的函数参数具有属性(通过 `argAttrs` 访问),这些属性会被附加到字段 op 上;否则,该字段将被创建而不带任何额外属性。 **Example / 示例:** ```mlir emitc.func @model(%input_data : !emitc.array<1xf32> {emitc.opaque = "input_tensor"}) attributes { } { %0 = "emitc.constant"() <{value = 0 : index}> : () -> !emitc.size_t %1 = subscript %input_data[%0] : (!emitc.array<1xf32>, !emitc.size_t) -> !emitc.lvalue return } // becomes emitc.class @modelClass { emitc.field @input_tensor : !emitc.array<1xf32> {emitc.opaque = "input_tensor"} emitc.func @operator() { %0 = "emitc.constant"() <{value = 0 : index}> : () -> !emitc.size_t %1 = get_field @input_tensor : !emitc.array<1xf32> %2 = subscript %1[%0] : (!emitc.array<1xf32>, !emitc.size_t) -> !emitc.lvalue return } } ``` **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-func-name` | The name of the newly generated member function with body matching the input function. | 与输入函数主体相匹配的新生成成员函数的名称。 | | `-class-name-format` | Format string for the generated class name where the function name placeholder '{}' is optional. | 生成类名的格式字符串,其中函数名占位符 `'{}'` 是可选的。 | --- ## ‘func’ Dialect Passes(‘func’ 方言 Pass) ### -duplicate-function-elimination **EN:** Deduplicate functions **中文:** 对函数进行去重。 **EN:** Deduplicate functions that are equivalent in all aspects but their symbol name. The pass chooses one representative per equivalence class, erases the remainder, and updates function calls accordingly. **中文:** 去重那些除符号名(symbol name)之外在所有方面都等价的函数。该 Pass 会为每个等价类(equivalence class)选出一个代表,擦除其余的重复函数,并相应地更新对它们的函数调用。 --- ## ‘gpu’ Dialect Passes(‘gpu’ 方言 Pass) ### -gpu-async-region **EN:** Make GPU ops async **中文:** 使 GPU op 异步化。 ### -gpu-decompose-memrefs **EN:** Decomposes memref index computation into explicit ops. This pass decomposes memref index computation into explicit computations on sizes/strides, obtained from memref.extract_memref_metadata which it tries to place outside of gpu.launch body. Memrefs are then reconstructed using memref.reinterpret_cast . This is needed for as some targets (SPIR-V) lower memrefs to bare pointers and sizes/strides for dynamically-sized memrefs are not available inside gpu.launch . **中文:** 将 memref 索引计算分解为显式的 op(算子)。该 Pass 将 memref 的索引计算分解为针对 sizes/strides(大小/步长)的显式计算,这些信息从 `memref.extract_memref_metadata` 获取,并尝试将其放置在 `gpu.launch` body(函数体)之外。随后使用 `memref.reinterpret_cast` 重建 Memrefs。之所以需要这样做,是因为某些目标(如 SPIR-V)将 memrefs lower(降级)为 bare pointers(裸指针),且动态大小 memrefs 的 sizes/strides 在 `gpu.launch` 内部不可用。 ### -gpu-eliminate-barriers **EN:** Erase unnecessary barriers Barrier elimination pass. If a barrier does not enforce any conflicting pair of memory effects, including a pair that is enforced by another barrier, it is unnecessary and can be removed. Adapted from "High-Performance GPU-toCPU Transpilation and Optimization via High-Level Parallel Constructs" by Moses, Ivanov, Domke, Endo, Doerfert, and Zinenko in PPoPP 2023 and implementation in Polygeist. **中文:** 擦除不必要的 barrier(屏障)。Barrier 消除 Pass。如果一个 barrier 没有强制任何一对冲突的 memory effects(内存效应)——包括被另一个 barrier 所强制的那对——那么它就是不必要的,可以被移除。改编自 Moses、Ivanov、Domke、Endo、Doerfert 和 Zinenko 在 PPoPP 2023 发表的 "High-Performance GPU-toCPU Transpilation and Optimization via High-Level Parallel Constructs"(通过高层并行构造实现高性能 GPU-to-CPU 转译与优化)一文,以及 Polygeist 中的实现。 ### -gpu-kernel-outlining **EN:** Outline gpu.launch bodies to kernel functions **中文:** 将 `gpu.launch` body(函数体)outline(提取轮廓化)为 kernel function(内核函数)。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-data-layout-str` | String description of the data layout | 数据布局的字符串描述 | ### -gpu-launch-sink-index-computations **EN:** Sink index computations into gpu.launch body **中文:** 将索引计算下沉(sink)到 `gpu.launch` body(函数体)内。 ### -gpu-map-parallel-loops **EN:** Greedily maps loops to GPU hardware dimensions. Maps the parallel loops found in the given function to workgroups. The first loop encountered will be mapped to the global workgroup and the second loop encountered to the local workgroup. Within each mapping, the first three dimensions are mapped to x/y/z hardware ids and all following dimensions are mapped to sequential loops. Ordering of the loop mapping against the different dimensions is controlled by the mapping-policy option. Two policies are supported: 1. outermost-first (default): the outermost loop maps to X, then Y and finally Z. 2. innermost-first : the innermost loop maps to X, then Y and finally Z. **中文:** 贪婪地将循环映射到 GPU 硬件维度。将给定函数中发现的并行循环映射到 workgroups(工作组)。遇到的第一个循环将被映射到 global workgroup(全局工作组),第二个遇到的循环将被映射到 local workgroup(局部工作组)。在每次映射中,前三个维度被映射到 x/y/z 硬件 id,其余所有后续维度被映射为 sequential loops(顺序循环)。循环在不同维度上的映射顺序由 `mapping-policy` option(选项)控制。支持两种策略: 1. outermost-first(最外层优先,默认值):最外层循环映射到 X,然后是 Y,最后是 Z。 2. innermost-first(最内层优先):最内层循环映射到 X,然后是 Y,最后是 Z。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-mapping-policy` | Policy outlining how to assign loops to GPU dimensions.Supported values are `outermost-first` and `innermost-first`. | 描述如何将循环分配到 GPU 维度的策略。支持的值是 `outermost-first` 和 `innermost-first`。 | ### -gpu-module-to-binary **EN:** Transforms a GPU module into a GPU binary. This pass searches for all nested GPU modules and serializes the module using the target attributes attached to the module, producing a GPU binary with an object for every target. The format argument can have the following values: 1. offloading , llvm : produces an offloading representation. 2. assembly , isa : produces assembly code. 3. binary , bin : produces binaries. 4. fatbinary , fatbin : produces fatbinaries. **中文:** 将 GPU module(模块)转换为 GPU binary(二进制)。该 Pass 搜索所有嵌套的 GPU modules,并使用附加在该 module 上的 target attributes(目标属性)对其进行 serialize(序列化),生成一个为每个 target(目标)都包含 object 的 GPU binary。`format` argument(参数)可取以下值: 1. `offloading`、`llvm`:生成 offloading representation(卸载表示)。 2. `assembly`、`isa`:生成汇编代码。 3. `binary`、`bin`:生成二进制文件。 4. `fatbinary`、`fatbin`:生成 fatbinaries(胖二进制文件)。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-toolkit` | Toolkit path. | 工具包路径。 | | `-l` | Extra files to link to. | 要链接的额外文件。 | | `-opts` | Command line options to pass to the tools. | 传递给工具的命令行选项。 | | `-format` | The target representation of the compilation process. | 编译过程的目标表示形式。 | | `-section` | ELF section where binary is to be located. | 二进制文件要放置的 ELF section(节)。 | ### -nvvm-attach-target **EN:** Attaches an NVVM target attribute to a GPU Module. This pass searches for all GPU Modules in the immediate regions and attaches an NVVM target if the module matches the name specified by the module argument. **中文:** 将一个 NVVM target attribute(目标属性)附加到 GPU Module(模块)上。该 Pass 搜索直接区域(immediate regions)中的所有 GPU Modules,如果 module 的名称与 `module` argument(参数)指定的名称匹配,则为其附加一个 NVVM target(目标)。 **Example / 示例:** ```mlir // File: in.mlir: gpu.module @nvvm_module_1 {...} gpu.module @nvvm_module_2 {...} gpu.module @rocdl_module_1 {...} // mlir-opt --nvvm-attach-target="module=nvvm.* chip=sm_90" in.mlir gpu.module @nvvm_module_1 [#nvvm.target] {...} gpu.module @nvvm_module_2 [#nvvm.target] {...} gpu.module @rocdl_module_1 {...} ``` **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-module` | Regex used to identify the modules to attach the target to. | 用于识别要附加该 target 的 module 的正则表达式。 | | `-triple` | Target triple. | 目标三元组 (target triple)。 | | `-chip` | Target chip. | 目标芯片。 | | `-features` | Target features. | 目标特性。 | | `-O` | Optimization level. | 优化级别。 | | `-fast` | Enable fast math mode. | 启用快速数学模式 (fast math)。 | | `-ftz` | Enable flush to zero for denormals. | 对非规格化数(denormals)启用 flush to zero(刷新为零)。 | | `-collect-compiler-diagnostics` | Enable collection of compiler diagnostics. | 启用编译器诊断信息收集。 | | `-l` | Extra bitcode libraries paths to link to. | 要链接的额外 bitcode 库路径。 | | `-ptxas-cmd-options` | Command line options passed to downstream compiler | 传递给下游编译器的命令行选项 | | `-verify-target-arch` | Enable verification of the target architecture | 启用目标架构验证 | ### -rocdl-attach-target **EN:** Attaches a ROCDL target attribute to a GPU Module. This pass searches for all GPU Modules in the immediate regions and attaches a ROCDL target if the module matches the name specified by the module argument. **中文:** 将一个 ROCDL target attribute(目标属性)附加到 GPU Module(模块)上。该 Pass 搜索直接区域(immediate regions)中的所有 GPU Modules,如果 module 的名称与 `module` argument(参数)指定的名称匹配,则为其附加一个 ROCDL target(目标)。 **Example / 示例:** ```mlir // File: in.mlir: gpu.module @nvvm_module_1 {...} gpu.module @nvvm_module_2 {...} gpu.module @rocdl_module_1 {...} // mlir-opt --nvvm-attach-target="module=rocdl.* chip=gfx90a" in.mlir gpu.module @nvvm_module_1 {...} gpu.module @nvvm_module_2 {...} gpu.module @rocdl_module_1 [#rocdl.target] {...} ``` **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-module` | Regex used to identify the modules to attach the target to. | 用于识别要附加该 target 的 module 的正则表达式。 | | `-triple` | Target triple. | 目标三元组 (target triple)。 | | `-chip` | Target chip. | 目标芯片。 | | `-features` | Target features. | 目标特性。 | | `-abi` | ABI version. | ABI 版本。 | | `-O` | Optimization level. | 优化级别。 | | `-wave64` | Use Wave64 mode. | 使用 Wave64 模式。 | | `-fast` | Enable fast relaxed math opt. | 启用快速宽松数学优化 (fast relaxed math)。 | | `-daz` | Enable denormals are zero opt. | 启用非规格化数视为零优化(denormals-are-zero)。 | | `-finite-only` | Enable finite only opt. | 启用仅限有限值优化(finite only)。 | | `-unsafe-math` | Enable unsafe math opt. | 启用不安全数学优化 (unsafe math)。 | | `-correct-sqrt` | Enable correct rounded sqrt. | 启用正确舍入的平方根。 | | `-l` | Extra bitcode libraries paths to link to. | 要链接的额外 bitcode 库路径。 | ### -spirv-attach-target **EN:** Attaches an SPIR-V target attribute to a GPU Module. This pass searches for all GPU Modules in the immediate regions and attaches an SPIR-V target if the module matches the name specified by the module argument. **中文:** 将一个 SPIR-V target attribute(目标属性)附加到 GPU Module(模块)上。该 Pass 搜索直接区域(immediate regions)中的所有 GPU Modules,如果 module 的名称与 `module` argument(参数)指定的名称匹配,则为其附加一个 SPIR-V target(目标)。 **Example / 示例:** ```mlir // Given the following file: in1.mlir: gpu.module @nvvm_module_1 {...} gpu.module @spirv_module_1 {...} // With // mlir-opt --spirv-attach-target="module=spirv.* ver=v1.0 caps=Kernel" in1.mlir // it will generate, gpu.module @nvvm_module_1 {...} gpu.module @spirv_module_1 [#spirv.target<#spirv.vce, #spirv.resource_limits<>>] {...} ``` **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-module` | Regex used to identify the modules to attach the target to. | 用于识别要附加该 target 的 module 的正则表达式。 | | `-ver` | SPIR-V Version. | SPIR-V 版本。 | | `-caps` | List of supported SPIR-V Capabilities | 支持的 SPIR-V Capabilities(能力)列表 | | `-exts` | List of supported SPIR-V Extensions | 支持的 SPIR-V Extensions(扩展)列表 | | `-client_api` | Client API | 客户端 API | | `-vendor` | Device Vendor | 设备供应商 | | `-device_type` | Device Type | 设备类型 | | `-device_id` | Device ID | 设备 ID | ### -xevm-attach-target **EN:** Attaches a XeVM target attribute to a GPU Module. This pass searches for all GPU Modules in the immediate regions and attaches a XeVM target if the module matches the name specified by the module argument. **中文:** 将一个 XeVM target attribute(目标属性)附加到 GPU Module(模块)上。该 Pass 搜索直接区域(immediate regions)中的所有 GPU Modules,如果 module 的名称与 `module` argument(参数)指定的名称匹配,则为其附加一个 XeVM target(目标)。 **Example / 示例:** ```mlir // File: in.mlir: gpu.module @nvvm_module_1 {...} gpu.module @rocdl_module_2 {...} gpu.module @xevm_module_3 {...} // mlir-opt --xevm-attach-target="module=xevm.* chip=pvc" in.mlir gpu.module @nvvm_module_1 {...} gpu.module @rocdl_module_2 {...} gpu.module @xevm_module_3 [#xevm.target] {...} ``` **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-module` | Regex used to identify the modules to attach the target to. | 用于识别要附加该 target 的 module 的正则表达式。 | | `-triple` | Target triple. | 目标三元组 (target triple)。 | | `-chip` | Target chip. | 目标芯片。 | | `-O` | Optimization level. | 优化级别。 | | `-l` | Extra bitcode libraries paths to link to. | 要链接的额外 bitcode 库路径。 | | `-cmd-options` | Command line options passed to downstream compiler | 传递给下游编译器的命令行选项 | --- ## ’linalg’ Dialect Passes('linalg' 方言 Pass) ### -convert-elementwise-to-linalg **EN:** Convert ElementwiseMappable ops to linalg **中文:** 将 ElementwiseMappable op 转换为 linalg。 **EN:** Convert ops with the ElementwiseMappable trait to linalg parallel loops. This pass only converts ops that operate on ranked tensors. It can be run on op which contains linalg ops (most commonly a FunctionOpInterface op). **中文:** 将带有 ElementwiseMappable trait(特征)的 op 转换为 linalg 并行循环。该 Pass 只转换作用于带秩张量(ranked tensor)的 op,可以运行在包含 linalg op 的 op(最常见的是 FunctionOpInterface op)上。 ### -convert-linalg-to-affine-loops **EN:** Lower the operations from the linalg dialect into affine loops **中文:** 将 linalg 方言中的操作降级为 affine 循环。 ### -convert-linalg-to-loops **EN:** Lower the operations from the linalg dialect into loops **中文:** 将 linalg 方言中的操作降级为循环。 **EN:** Lowers the linalg ops to loop nests using scf.for . Pre-condition: the operands used by the linalg ops have buffer semantics, i.e., tensor operands and results must be converted to memrefs via bufferization. **中文:** 使用 scf.for 将 linalg op 降级为循环嵌套(loop nest)。前置条件(pre-condition):linalg op 所使用的操作数具有 buffer 语义,即张量操作数和结果必须通过 bufferization(缓冲化)转换为 memref。 ### -convert-linalg-to-parallel-loops **EN:** Lower the operations from the linalg dialect into parallel loops **中文:** 将 linalg 方言中的操作降级为并行循环。 ### -linalg-block-pack-matmul **EN:** Convert linalg matmul ops to block layout and back **中文:** 将 linalg matmul op 转换为块(block)布局,之后再转换回原布局。 **EN:** Pack a matmul operation into blocked layout with two levels of subdivision: major 2D blocks - outer dimensions, consist of minor blocks; minor 2D blocks - inner dimensions, consist of scalar elements **中文:** 将 matmul 操作打包(pack)为带有两级划分的块布局:主 2D 块(major 2D block)——对应外部维度,由次级块构成;次 2D 块(minor 2D block)——对应内部维度,由标量元素构成。 **EN:** A 2D matmul MxNxK gets reshaped into blocked 4D representation as: [MB][NB][mb][nb] += [MB][KB][mb][kb] * [NB][KB][nb][kb] where the (MB, NB, KB) dimensions represent the major blocks, and the (mb, nb, kb) are the minor blocks of their respective original 2D dimensions (M, N, K). **中文:** 一个 MxNxK 的 2D matmul 被 reshape 为块化的 4D 表示:[MB][NB][mb][nb] += [MB][KB][mb][kb] * [NB][KB][nb][kb],其中 (MB, NB, KB) 维度表示主块(major blocks),(mb, nb, kb) 分别是其原始 2D 维度 (M, N, K) 的次级块(minor blocks)。 **EN:** Depending on the initial operands' data layout and the specified packing options, the major blocks dimensions might get transposed e.g., [MB][KB] -> [KB][MB]. The minor blocks can also be transposed e.g., [mb][kb] -> [kb] [mb]. Any present batch dimensions remain unchanged. The final result is unpacked back to the original shape. **中文:** 根据初始操作数的数据布局以及指定的打包选项,主块维度可能会被转置(transpose),例如 [MB][KB] -> [KB][MB]。次级块同样可以被转置,例如 [mb][kb] -> [kb] [mb]。若存在 batch 维度则保持不变。最终结果会被解包(unpack)回原始形状。 **EN:** For example, given a matmul operation: **中文:** 例如,给定一个 matmul 操作: ```mlir %res = linalg.matmul ins(%A, %B) outs(%C) ``` **EN:** the default transformation result can be represented as: **中文:** 默认的变换结果可以表示为: ```mlir %A_packed = pack %A : 2D -> 4D %B_packed = pack %B : 2D -> 4D %C_packed = pack %C : 2D -> 4D %res_packed = linalg.mmt4d ins(%A_packed, %B_packed) outs(%C_packed) %res = unpack %res_packed : 4D -> 2D ``` **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-block-factors` | Block factors (mb, nb, kb) for relayout; use [N] for scalable | 用于重新布局(relayout)的块因子(mb、nb、kb);使用 [N] 表示可缩放维度 | | `-allow-padding` | Allow packing padding | 允许 pack 填充(padding) | | `-mnk-padded-multiples` | Next multiples of the packing sizes | 打包尺寸的下一个倍数 | | `-mnk-order` | Permutation of matmul (M, N, K) dimensions order | matmul(M、N、K)维度顺序的排列(permutation) | | `-lhs-transpose-outer-blocks` | Transpose LHS outer block layout [MB][KB] -> [KB][MB] | 转置左操作数(LHS)外层块布局 [MB][KB] -> [KB][MB] | | `-lhs-transpose-inner-blocks` | Transpose LHS inner block layout [mb][kb] -> [kb][mb] | 转置左操作数(LHS)内层块布局 [mb][kb] -> [kb][mb] | | `-rhs-transpose-outer-blocks` | Transpose RHS outer block layout [KB][NB] -> [NB][KB] | 转置右操作数(RHS)外层块布局 [KB][NB] -> [NB][KB] | | `-rhs-transpose-inner-blocks` | Transpose RHS inner block layout [kb][nb] -> [nb][kb] | 转置右操作数(RHS)内层块布局 [kb][nb] -> [nb][kb] | ### -linalg-fold-into-elementwise **EN:** Fold transpose and broadcast ops into elementwise consumers **中文:** 将 transpose(转置)和 broadcast(广播)op 折叠进逐元素(elementwise)消费者。 **EN:** Fold a transpose or broadcast that feeds a linalg.elementwise or an elementwise-like linalg.generic into its consumer. linalg.transpose and linalg.broadcast producers whose consumer indexing map is a projected permutation can be absorbed into the consumer's indexing map by composing the producer's map into it. Other operands remain untouched. **中文:** 将喂给 linalg.elementwise 或类逐元素(elementwise-like)linalg.generic 的 transpose 或 broadcast 折叠进其消费者。若消费者的索引映射(indexing map)是一个投影置换(projected permutation),则 linalg.transpose 与 linalg.broadcast 生产者可以通过将其自身的映射组合(compose)进来,从而被吸收进消费者的索引映射中。其他操作数保持不动。 ### -linalg-fold-unit-extent-dims **EN:** Remove unit-extent dimension in Linalg ops on tensors **中文:** 移除张量上的 Linalg op 中的单位长度维度(unit-extent dimension)。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-use-rank-reducing-slices` | Generate rank-reducing slices instead of reassociative reshapes | 生成降秩切片(rank-reducing slice),而不是可重结合(reassociative)的 reshape | ### -linalg-fuse-elementwise-ops **EN:** Fuse elementwise operations on tensors **中文:** 融合张量上的逐元素操作。 ### -linalg-generalize-named-ops **EN:** Convert named ops into generic ops **中文:** 将命名 op(named op)转换为通用 op(generic op)。 ### -linalg-inline-scalar-operands **EN:** Inline scalar operands into linalg generic ops **中文:** 将标量操作数内联(inline)到 linalg 通用 op 中。 ### -linalg-morph-ops **EN:** Convert linalg ops between forms **中文:** 在 linalg op 的不同形式之间进行转换。 **EN:** Convert a linalg op from one representation to another equivalent. For example, a linalg named op linalg.add can also be written as an category op linalg.elementwise , and can also be re-written as a linalg.generic , giving the morphism: named-op <–> category_op (elementwise, contraction, ..) <–> generic **中文:** 将一个 linalg op 从一种表示转换为另一种等价表示。例如,linalg 命名 op `linalg.add` 也可以写成类别 op(category op)`linalg.elementwise` ,还可以改写为 `linalg.generic` ,从而得到如下形态变换(morphism):named-op <–> category_op (elementwise, contraction, ..) <–> generic **EN:** Note that the set of linalg.generic subsumes named and category ops and therefore not all linalg.genric can be converted to named or category op. Similarly, catgory ops subsume named ops. **中文:** 注意,linalg.generic 的集合涵盖了命名 op 与类别 op,因此并非所有的 linalg.genric(原文如此)都能转换为命名或类别 op。类似地,catgory(原文如此)op 涵盖命名 op。 **EN:** Note: Legacy converters: --linalg-generalize-named-ops is the path named-op --> generic-op --linalgspecialize-generic-ops is the path named-op <-- generic-op **中文:** 注意:旧版转换器(legacy converter):--linalg-generalize-named-ops 是「命名 op → 通用 op」的路径;--linalgspecialize-generic-ops 是「命名 op ← 通用 op」的路径。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-named-to-category` | convert named ops to category op e.g. `linalg.elementwise` | 将命名 op 转换为类别 op,例如 `linalg.elementwise` | | `-category-to-generic` | convert category ops e.g. `linalg.elementwise` to `linalg.generic` | 将类别 op(例如 `linalg.elementwise`)转换为 `linalg.generic` | | `-named-to-generic` | convert named ops e.g. `linalg.add` to `linalg.generic` | 将命名 op(例如 `linalg.add`)转换为 `linalg.generic` | | `-generic-to-named` | convert linalg.generic to equivalent named ops | 将 linalg.generic 转换为等价的命名 op | | `-generic-to-category` | convert linalg.generic to equivalent category ops | 将 linalg.generic 转换为等价的类别 op | | `-category-to-named` | convert category ops e.g. `linalg.elementwise` to equivalent named ops | 将类别 op(例如 `linalg.elementwise`)转换为等价的命名 op | ### -linalg-specialize-generic-ops **EN:** Convert generic ops back to named ops **中文:** 将通用 op(generic op)转换回命名 op(named op)。 ### -simplify-depthwise-conv **EN:** Simplify depthwise convolution. **中文:** 简化深度卷积(depthwise convolution)。 --- ## ’llvm’ Dialect Passes('llvm' 方言 Pass) ### -ensure-debug-info-scope-on-llvm-func **EN:** Materialize LLVM debug info subprogram attribute on every LLVMFuncOp Having a debug info subprogram attribute on a function is required for emitting line tables from MLIR FileLocCol locations. This is not intended to be a proper replacement for frontends to emit complete debug information, however it is a convenient way to get line tables for debugging purposes. This allow to step trough in a debugger line-by-line or get a backtrace with line numbers. **中文:** 在每个 LLVMFuncOp(LLVM 函数 op)上物化(materialize)LLVM 调试信息 subprogram(子程序)属性。要在从 MLIR FileLocCol location(文件列位置定位)发射行表(line table)时,函数上必须带有调试信息 subprogram 属性。这并不旨在作为前端输出完整调试信息的正式替代方案,但它是一种为调试目的获取行表的便捷方式。它允许在调试器中逐行单步执行,或获取带行号的回溯(backtrace)。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-emission-kind` | Emission kind to generate debug info. | 生成调试信息所用的发射种类(emission kind) | ### -llvm-add-comdats **EN:** Add comdats to linkonce and linkonce_odr functions Add an any COMDAT to every linkonce and linkonce_odr function. This is necessary on Windows to link these functions as the system linker won’t link weak symbols without a COMDAT. It also provides better behavior than standard weak symbols on ELF-based platforms. This pass will still add COMDATs on platforms that do not support them, for example macOS, so should only be run when the target platform supports COMDATs. **中文:** 为 linkonce 和 linkonce_odr 函数添加 comdat(COMDAT):为每个 linkonce 和 linkonce_odr 函数添加任意一个 COMDAT。在 Windows 上这是链接这些函数所必需的,因为系统链接器在没有 COMDAT 的情况下不会链接弱符号(weak symbol)。对于基于 ELF 的平台,它也比标准弱符号提供更好的行为。本 pass 即使在不支持 COMDAT 的平台(例如 macOS)上仍会添加 COMDAT,因此只应在目标平台支持 COMDAT 时运行。 ### -llvm-legalize-for-export **EN:** Legalize LLVM dialect to be convertible to LLVM IR Creates a pass that legalizes the LLVM dialect operations so that they can be translated to LLVM IR. **中文:** 对 LLVM 方言进行合法化(legalization)以使其可转换为 LLVM IR:创建一个 pass,将 LLVM 方言的 op 合法化,以便它们能被翻译为 LLVM IR。 ### -llvm-request-c-wrappers **EN:** Request C wrapper emission for all functions Annotate every builtin function in the module with the LLVM dialect attribute that instructs the conversion to LLVM to emit the C wrapper for the function. This pass is expected to be applied immediately before the conversion of builtin functions to LLVM to avoid the attribute being dropped by other passes. **中文:** 为所有函数请求发射(emit)C wrapper:用 LLVM 方言属性标注模块中的每个内建(builtin)函数,该属性指示到 LLVM 的转换为相应函数发射 C wrapper。本 pass 预期在将内建函数转换为 LLVM 之前立即应用,以避免该属性被其他 pass 丢弃。 ### -llvm-use-default-visibility **EN:** Update default visibility of all global values and function definitions Update the default visibility of all global values and function definitions to visibility , as with -fvisibility= (hidden|protected). **中文:** 更新所有全局值(global value)和函数定义(function definition)的默认可见性:将所有全局值和函数定义的默认可见性更新为 visibility,类似于 -fvisibility=(hidden|protected)。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-visibility` | Visibility to use in place of default. | 用于替代默认值的可见性(visibility) | --- ## 'llvm' Target Passes('llvm' 目标 Pass) ### -llvm-target-to-data-layout **EN:** Derive data layout attributes from LLVM target attributes **中文:** 从 LLVM 目标属性中推导数据布局(data layout)属性。 **EN:** Derive a DataLayoutSpecInterface -implementing data layout attribute from the LLVM-backend target specified by the TargetAttrInterface -implementing attribute attached to the target op at the name llvm.target . **中文:** 从附加在 `llvm.target` 名称处的、实现了 TargetAttrInterface 的属性所指定的 LLVM 后端目标,推导出一个实现了 DataLayoutSpecInterface 的数据布局属性。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-initialize-llvm-targets` | Whether to pre-load all available target machines, that LLVM is configured to support, into the TargetRegistry. | 是否将 LLVM 配置为支持的所有可用目标机器预加载到 TargetRegistry(目标注册表)中。 | ### -llvm-target-to-target-features **EN:** Update attached #llvm.target's features per the described target **中文:** 根据所描述的目标更新已附加的 `#llvm.target` 的特性(features)。 **EN:** Obtain the TargetMachine specified by the attached #llvm.target's attributes and obtain from it the full list of features of the selected target. Updates the attached #llvm.target so that its features reflect the full list of features. **中文:** 获取已附加的 `#llvm.target` 属性所指定的 TargetMachine,并从中获取所选目标的完整特性列表。更新已附加的 `#llvm.target`,使其特性反映完整的特性列表。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-initialize-llvm-targets` | Whether to pre-load all available target machines, that LLVM is configured to support, into the TargetRegistry. | 是否将 LLVM 配置为支持的所有可用目标机器预加载到 TargetRegistry(目标注册表)中。 | --- ## 'math' Dialect Passes('math' 方言 Pass) ### -math-expand-ops **EN:** Expand math operations. **中文:** 展开数学运算。 **EN:** Expands some math operations into more fundamental operations, allowing them to be subsequently lowered through these. For example, hyperbolic functions are transformed into their expanded form containing only exp functions. **中文:** 将一些数学运算展开为更基础的运算,使其随后可以通过这些基础运算进行 lowering(降级)。例如,双曲函数会被变换成仅包含 exp 函数的展开形式。 **EN:** The ops parameter can be used to apply only a subset of all the available expansions, these must correspond to the operation mnemonic. For example, ops=sinh,acosh will expand only math.sinh and math.acosh operations. If the list is empty, then all expansions are applied. **中文:** 可以使用 ops 参数来仅应用所有可用展开(expansions)中的一个子集,这些必须对应运算的助记符(mnemonic)。例如,ops=sinh,acosh 只会展开 math.sinh 和 math.acosh 运算。如果列表为空,则应用所有展开。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-ops` | Operations to expand. | 要展开的运算(对应 operation mnemonic)。 | ### -math-extend-to-supported-types **EN:** Legalize floating-point math ops on low-precision floats **中文:** 在低精度浮点上合法化(legalize)浮点数学运算。 **EN:** On many targets, the math functions are not implemented for floating-point types less precise than IEEE singleprecision (aka f32), such as half-floats, bfloat16, or 8-bit floats. **中文:** 在许多目标(target)上,对于精度低于 IEEE singleprecision(即 f32)的浮点类型——例如半精度浮点数(half-floats)、bfloat16、或 8 位浮点数——并没有实现相应的数学函数。 **EN:** This pass explicitly legalizes these math functions by inserting arith.extf and arith.truncf pairs around said op, which preserves the original semantics while enabling lowering. The extra supported floating-point types for the target are passed as arguments. Types f64 and f32 are implicitly supported. **中文:** 本 pass 通过在相应运算(op)周围插入 arith.extf 和 arith.truncf 配对来显式合法化这些数学函数,这既保留了原有语义又使 lowering 成为可能。目标额外支持的浮点类型作为参数传入。类型 f64 和 f32 被隐式支持。 **EN:** As an exception, this pass does not legalize math.fma , because that is an operation frequently implemented at low precisions. **中文:** 作为一个例外,本 pass 不会合法化 math.fma ,因为这是一个经常在低精度下实现的运算。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-extra-types` | MLIR types with arithmetic support on a given target (f64 and f32 are implicitly supported) | 在给定目标上支持算术运算的 MLIR 类型(f64 和 f32 被隐式支持) | | `-target-type` | MLIR type to convert the unsupported source types to | 将不支持的源类型转换成的目标 MLIR 类型 | ### -math-sincos-fusion **EN:** Fuse sin and cos operations. **中文:** 融合(fuse)sin 和 cos 运算。 **EN:** Fuse sin and cos operations into a sincos operation. **中文:** 将 sin 和 cos 运算融合为一个 sincos 运算。 ### -math-uplift-to-fma **EN:** Uplift arith ops to math.fma. **中文:** 将算术(arith)运算上提(uplift)为 math.fma。 **EN:** Uplift sequence of addf and mulf ops to math.fma if fastmath flags allows it. **中文:** 如果 fastmath 标志允许,则将连续的 addf 和 mulf 运算序列上提为 math.fma。 --- ## 'memref' Dialect Passes('memref' 方言 Pass) ### -expand-realloc **EN:** Expand memref.realloc operations into its components **中文:** 将 memref.realloc 操作展开为其组成部分 **EN:** The memref.realloc operation performs a conditional allocation and copy to increase the size of a buffer if necessary. This pass converts a realloc operation into this sequence of simpler operations such that other passes at a later stage in the compilation pipeline do not have to consider the realloc operation anymore (e.g., the buffer deallocation pass and the conversion pass to LLVM). **中文:** memref.realloc 操作执行一次条件分配与拷贝,以便在必要时增大缓冲区(buffer)的大小。本 Pass 将 realloc 操作转换为这一系列更简单的操作,使得编译流水线后续阶段的其他 Pass 不再需要考虑 realloc 操作(例如 buffer deallocation pass(缓冲区释放 Pass)以及到 LLVM 的转换 Pass)。 **Example of an expansion / 扩展示例:** ```mlir %realloc = memref.realloc %alloc (%size) : memref to memref ``` **EN:** is expanded to **中文:** 被展开为: ```mlir %c0 = arith.constant 0 : index %dim = memref.dim %alloc, %c0 : memref %is_old_smaller = arith.cmpi ult, %dim, %arg1 %realloc = scf.if %is_old_smaller -> (memref) { %new_alloc = memref.alloc(%size) : memref %subview = memref.subview %new_alloc[0] [%dim] [1] memref.copy %alloc, %subview memref.dealloc %alloc scf.yield %alloc_0 : memref } else { %reinterpret_cast = memref.reinterpret_cast %alloc to offset: [0], sizes: [%size], strides: [1] scf.yield %reinterpret_cast : memref } ``` **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-emit-deallocs` | Emit deallocation operations for the original MemRef | 为原始 MemRef 发出释放(deallocation)操作 | ### -expand-strided-metadata **EN:** Expand memref operations into easier to analyze constructs **中文:** 将 memref 操作展开为更易于分析的结构 **EN:** The pass expands memref operations that modify the metadata of a memref (sizes, offset, strides) into a sequence of easier to analyze constructs. In particular, this pass transforms operations into explicit sequence of operations that model the effect of this operation on the different metadata. This pass uses affine constructs to materialize these effects. **中文:** 本 Pass 将那些修改 memref 元数据(metadata)(即 sizes、offset、strides)的 memref 操作,展开为更易于分析的一系列结构。具体而言,本 Pass 将这些操作转换为一系列显式的操作序列,用以建模该操作对不同元数据所产生的影响。本 Pass 使用 affine constructs(仿射结构)来实体化这些效果。 **EN:** Supported ops include: **中文:** 支持的 op(操作)包括: - `memref.collapse_shape` - `memref.expand_shape` - `memref.extract_aligned_pointer_as_index` - `memref.extract_strided_metadata` - `memref.subview` ### -flatten-memref **EN:** Flatten a multiple dimensional memref to 1-dimensional **中文:** 将多维 memref 展平为一维 ### -fold-memref-alias-ops **EN:** Fold memref alias ops into consumer load/store ops **中文:** 将 memref 别名(alias)操作折叠进消费者端的 load/store 操作中 **EN:** The pass folds loading/storing from/to memref aliasing ops to loading/storing from/to the original memref. **中文:** 本 Pass 将对 memref 别名操作的读取/写入,折叠为对原始 memref 的读取/写入。 ### -memref-elide-reinterpret-cast **EN:** Replace ops depending on redundant reinterpret_cast(s) to be convertible to EmitC. **中文:** 替换掉那些依赖于冗余 reinterpret_cast 的操作,使其可转换为 EmitC。 **EN:** Replace data-movement ops that depend on redundant memref.reinterpret_cast operations to obtain compatible shapes with equivalent ops that operate on compatible shapes directly. This simplifies conversion to EmitC. **中文:** 将那些依赖冗余的 memref.reinterpret_cast 操作来获得兼容 shape(形状)的数据搬运(data-movement)操作,替换为直接在兼容 shape 上操作的等价操作。这简化了到 EmitC 的转换。 ### -memref-emulate-wide-int **EN:** Emulate 2*N-bit integer operations using N-bit operations **中文:** 使用 N 位操作来模拟 2*N 位的整数运算 **EN:** Emulate memref integer operations that use too wide integer types with equivalent operations on supported narrow integer types. This is done by splitting original integer values into two halves. **中文:** 用受支持的窄整型(narrow integer type)上的等价操作,来模拟那些使用了过宽整数类型的 memref 整数运算。这通过将原始整数值一分为二来实现。 **EN:** Currently, only power-of-two integer bitwidths are supported. **中文:** 目前仅支持 2 的幂次(power-of-two)的整数位宽。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-widest-int-supported` | Widest integer type supported by the target | 目标平台所支持的最宽整型 | ### -memref-expand **EN:** Legalize memref operations to be convertible to LLVM. **中文:** 将 memref 操作合法化(legalize),使其可转换为 LLVM。 ### -normalize-memrefs **EN:** Normalize memrefs **中文:** 规范化(normalize)memrefs **EN:** This pass transforms memref types with a non-trivial layout map into memref types with an identity layout map, e.g. (i, j) -> (i, j). This pass is inter-procedural, in the sense that it can modify function interfaces and call sites that pass memref types. In order to modify memref types while preserving the original behavior, users of those memref types are also modified to incorporate the resulting layout map. For instance, an AffineLoadOp will be updated to compose the layout map with with the affine expression contained in the op. Operations marked with the MemRefsNormalizable trait are expected to be normalizable. Supported operations include affine operations, memref.alloc, memref.dealloc, and func.return. **中文:** 本 Pass 将带有非平凡 layout map(布局映射)的 memref 类型,转换为带有恒等(identity)layout map 的 memref 类型,例如 (i, j) -> (i, j)。本 Pass 是过程间(inter-procedural)的,也就是说它能够修改函数接口以及传递 memref 类型的调用点。为了在修改 memref 类型的同时保持原有行为,这些 memref 类型的使用者也会被相应修改以纳入所生成的 layout map。例如,一个 AffineLoadOp 会被更新为将 layout map 与 op 中所含的 affine expression(仿射表达式)进行组合(compose)。带有 MemRefsNormalizable trait 标记的操作被预期是可规范化的。受支持的操作包括 affine operations、memref.alloc、memref.dealloc 以及 func.return。 **EN:** Given an appropriate layout map specified in the code, this transformation can express tiled or linearized access to multi-dimensional data structures, but will not modify memref types without an explicit layout map. **中文:** 给定代码中指定的合适 layout map,这一变换可以表达对于多维数据结构的分块(tiled)或线性化(linearized)访问,但对于没有显式 layout map 的 memref 类型则不做修改。 **EN:** Currently this pass is limited to only modify functions where all memref types can be normalized. If a function contains any operations that are not MemRefNormalizable, then the function and any functions that call or call it will not be modified. **中文:** 目前本 Pass 仅限于修改那些所有 memref 类型都可被规范化的函数。如果某个函数包含任何不是 MemRefNormalizable 的操作,则该函数以及调用它的或被它调用的任何函数都不会被修改。 **Input / 输入:** ```mlir #tile = affine_map<(i) -> (i floordiv 4, i mod 4)> func.func @matmul(%A: memref<16xf64, #tile>, %B: index, %C: memref<16xf64>) -> (memref<16xf64, #tile>) { affine.for %arg3 = 0 to 16 { %a = affine.load %A[%arg3] : memref<16xf64, #tile> %p = arith.mulf %a, %a : f64 affine.store %p, %A[%arg3] : memref<16xf64, #tile> } %c = memref.alloc() : memref<16xf64, #tile> %d = affine.load %c[0] : memref<16xf64, #tile> return %A: memref<16xf64, #tile> } ``` **Output / 输出:** ```mlir func.func @matmul(%arg0: memref<4x4xf64>, %arg1: index, %arg2: memref<16xf64>) -> memref<4x4xf64> { affine.for %arg3 = 0 to 16 { %3 = affine.load %arg0[%arg3 floordiv 4, %arg3 mod 4]: memref<4x4xf64> %4 = arith.mulf %3, %3 : f64 affine.store %4, %arg0[%arg3 floordiv 4, %arg3 mod 4]: memref<4x4xf64> } %0 = memref.alloc() : memref<4x4xf64> %1 = affine.apply #map1() %2 = affine.load %0[0, 0] : memref<4x4xf64> return %arg0 : memref<4x4xf64> } ``` **Input / 输入:** ```mlir #linear8 = affine_map<(i, j) -> (i * 8 + j)> func.func @linearize(%arg0: memref<8x8xi32, #linear8>, %arg1: memref<8x8xi32, #linear8>, %arg2: memref<8x8xi32, #linear8>) { %c8 = arith.constant 8 : index %c0 = arith.constant 0 : index %c1 = arith.constant 1 : index affine.for %arg3 = %c0 to %c8 { affine.for %arg4 = %c0 to %c8 { affine.for %arg5 = %c0 to %c8 { %0 = affine.load %arg0[%arg3, %arg5] : memref<8x8xi32, #linear8> %1 = affine.load %arg1[%arg5, %arg4] : memref<8x8xi32, #linear8> %2 = affine.load %arg2[%arg3, %arg4] : memref<8x8xi32, #linear8> %3 = arith.muli %0, %1 : i32 %4 = arith.addi %2, %3 : i32 affine.store %4, %arg2[%arg3, %arg4] : memref<8x8xi32, #linear8> } } } return } ``` **Output / 输出:** ```mlir func.func @linearize(%arg0: memref<64xi32>, %arg1: memref<64xi32>, %arg2: memref<64xi32>) { %c8 = arith.constant 8 : index %c0 = arith.constant 0 : index affine.for %arg3 = %c0 to %c8 { affine.for %arg4 = %c0 to %c8 { affine.for %arg5 = %c0 to %c8 { %0 = affine.load %arg0[%arg3 * 8 + %arg5] : memref<64xi32> %1 = affine.load %arg1[%arg5 * 8 + %arg4] : memref<64xi32> %2 = affine.load %arg2[%arg3 * 8 + %arg4] : memref<64xi32> %3 = arith.muli %0, %1 : i32 %4 = arith.addi %2, %3 : i32 affine.store %4, %arg2[%arg3 * 8 + %arg4] : memref<64xi32> } } } return } ``` ### -reify-result-shapes **EN:** Reifies the results of tensor::PadOp and tensor::ConcatOp . **中文:** 对 tensor::PadOp 与 tensor::ConcatOp 的结果进行具体化(reify)。 **EN:** This pass reifies the shapes of a subset of ReifyRankedShapedTypeOpInterface ops with tensor results. **中文:** 本 Pass 对具有 tensor 结果的一部分 ReifyRankedShapedTypeOpInterface op(操作)的 shape(形状)进行具体化。 **EN:** The pass currently only supports result shape type reification for: **中文:** 本 Pass 目前仅支持以下 op 的结果 shape 类型具体化: - `tensor::PadOp` - `tensor::ConcatOp` **EN:** It addresses a representation gap where implicit op semantics are needed to infer static result types from dynamic operands. But it does so by using ReifyRankedShapedTypeOpInterface as the source of truth rather than the op itself. As a consequence, this cannot generalize today. **中文:** 它填补了一个表示上的空缺——即需要从动态操作数(operands)推断静态结果类型时所需的隐式 op 语义。但它是以 ReifyRankedShapedTypeOpInterface 作为唯一事实来源(source of truth),而非以 op 本身为依据。因此,这一做法目前无法被推广。 **EN:** TODO: in the future, we should consider coupling this information with op "transfer functions" (e.g. IndexingMapOpInterface ) to provide a source of truth that can work across result shape inference, canonicalization and op verifiers. **中文:** TODO(待办):未来,我们应考虑将此信息与 op 的"转移函数"(transfer functions,例如 IndexingMapOpInterface )耦合起来,从而提供一个能够贯穿结果 shape 推断、规范化(canonicalization)以及 op verifier(校验器)的统一事实来源。 **EN:** The pass replaces the operations with their reified versions, when more static information can be derived, and inserts casts when results shapes are updated. **中文:** 当能够推导出更多静态信息时,本 Pass 会用其具体化(reified)版本替换这些操作;并且在结果 shape 被更新时插入 cast(类型转换)。 **Example / 示例:** ```mlir #map = affine_map<(d0) -> (-d0 + 256)> func.func @func(%arg0: f32, %arg1: index, %arg2: tensor<64x?x64xf32>) -> tensor<1x?x64xf32> { %0 = affine.apply #map(%arg1) %extracted_slice = tensor.extract_slice %arg2[0, 0, 0] [1, %arg1, 64] [1, 1, 1] : tensor<64x?x64xf32> to tensor<1x?x64xf32> %padded = tensor.pad %extracted_slice low[0, 0, 0] high[0, %0, 0] { ^bb0(%arg3: index, %arg4: index, %arg5: index): tensor.yield %arg0 : f32 } : tensor<1x?x64xf32> to tensor<1x?x64xf32> return %padded : tensor<1x?x64xf32> } // mlir-opt --reify-result-shapes #map = affine_map<()[s0] -> (-s0 + 256)> func.func @func(%arg0: f32, %arg1: index, %arg2: tensor<64x?x64xf32>) -> tensor<1x?x64xf32> { %0 = affine.apply #map()[%arg1] %extracted_slice = tensor.extract_slice %arg2[0, 0, 0] [1, %arg1, 64] [1, 1, 1] : tensor<64x?x64xf32> to tensor<1x?x64xf32> %padded = tensor.pad %extracted_slice low[0, 0, 0] high[0, %0, 0] { ^bb0(%arg3: index, %arg4: index, %arg5: index): tensor.yield %arg0 : f32 } : tensor<1x?x64xf32> to tensor<1x256x64xf32> %cast = tensor.cast %padded : tensor<1x256x64xf32> to tensor<1x?x64xf32> return %cast : tensor<1x?x64xf32> } ``` ### -resolve-ranked-shaped-type-result-dims **EN:** Resolve memref.dim of result values of ranked shape type **中文:** 解析具有秩的 shape 类型的结果值上的 memref.dim **EN:** The pass resolves memref.dim of result of operations that implement the ReifyRankedShapedTypeOpInterface in terms of shapes of its operands. **中文:** 本 Pass 将那些实现了 ReifyRankedShapedTypeOpInterface 的操作的结果上的 memref.dim,用其操作数(operands)的 shape 来表示。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-error-on-pattern-iteration-limit` | Throw an error when pattern rewriter hits iteration limit | 当 pattern rewriter 达到迭代次数上限时抛出错误 | ### -resolve-shaped-type-result-dims **EN:** Resolve memref.dim of result values **中文:** 解析结果值上的 memref.dim **EN:** The pass resolves memref.dim of result of operations that implement the InferShapedTypeOpInterface or ReifyRankedShapedTypeOpInterface in terms of shapes of its operands. **中文:** 本 Pass 将那些实现了 InferShapedTypeOpInterface 或 ReifyRankedShapedTypeOpInterface 的操作的结果上的 memref.dim,用其操作数(operands)的 shape 来表示。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-error-on-pattern-iteration-limit` | Throw an error when pattern rewriter hits iteration limit | 当 pattern rewriter 达到迭代次数上限时抛出错误 | --- ## ‘omp’ Dialect Passes(‘omp’ 方言 Pass) ### -omp-host-op-filter **EN:** Removes all non target-related ops from host functions. When compiling for an OpenMP offloading target, host functions holding target regions must be maintained in order for the omp.target ops to be translated to LLVM IR as functions. However, these host functions might contain more host code than just what’s necessary for generating code for their contained target regions on the target device, potentially causing problematic artifacts to be generated into the target device’s module. This pass strips out all non-essential operations from host functions when compiling for an OpenMP target device, leaving just omp.target operations, related omp.map.info and placeholders in the form of function arguments to keep the MLIR representation legal. It must run on a module at a low level of abstraction (i.e. directly translatable to LLVM IR), after any passes that might produce new OpenMP operations have already completed. **中文:** 移除 host 函数中所有与 target(目标)无关的 op。在为 OpenMP offloading(卸载)目标编译时,持有 target region(目标区域)的 host 函数必须被保留下来,以便 omp.target op 能够被翻译为 LLVM IR 中的函数。然而,这些 host 函数可能包含比仅仅生成其内部 target region 在目标设备上代码所需更多的 host 代码,这可能导致生成有问题的产物到目标设备的 module(模块)中。本 Pass 在为 OpenMP 目标设备编译时,从 host 函数中剥离所有非必要的操作,仅保留 omp.target 操作、相关的 omp.map.info 以及以 function argument(函数参数)形式存在的占位符,以保持 MLIR 表示的合法性。它必须在较低抽象层次(即可直接翻译为 LLVM IR 的层次)的 module 上运行,并且要在任何可能产生新的 OpenMP 操作的 Pass 已经完成之后运行。 ### -omp-mark-declare-target **EN:** Marks all functions called by an OpenMP declare target function as declare target **中文:** 将所有被 OpenMP declare target 函数调用的函数标记为 declare target(声明目标)。 **EN:** Marks functions contained within the module as declare target if they are called from within an explicitly marked declare target function or a target region (omp.target). **中文:** 如果模块内的函数是从一个显式标记的 declare target 函数或一个 target region(target 区域,即 omp.target)内部调用的,则将这些函数标记为 declare target。 ### -omp-offload-privatization-prepare **EN:** Prepare OpenMP maps for privatization for deferred target tasks **中文:** 为延迟执行的 target task(目标任务)准备用于私有化(privatization)的 OpenMP map。 **EN:** When generating LLVMIR for privatized variables in an OpenMP offloading directive (eg. omp::TargetOp) that creates a deferred target task (when the nowait clause is used), we need to copy the privatized variable out of the stack of the generating task and into the heap so that the deferred target task can still access it. However, if such a privatized variable is also mapped, typically the case for allocatables, then the corresponding omp::MapInfoOp needs to be fixed up to map the new heap-allocated variable and not the original variable. **中文:** 当为一个 OpenMP offloading 指令(例如 omp::TargetOp)中私有化的变量生成 LLVMIR,且该指令创建一个延迟执行的 target task(即使用 nowait clause 时),我们需要把私有化变量从创建它的 task 的栈上复制到堆上,以便延迟的 target task 仍然能够访问它。然而,如果这样一个私有化变量同时被 map(映射)——对于可分配对象(allocatables)通常如此——那么相应的 omp::MapInfoOp 需要被修正为映射新的堆上分配的变量,而不是原来的变量。 ### -omp-stack-to-shared **EN:** Replaces stack allocations target devices with shared memory. **中文:** 在 target device(目标设备)上,将栈分配替换为共享内存。 **EN:** This pass replaces llvm.alloca operations located in a non-SPMD target region and then potentially used inside of an omp.parallel region with omp.alloc_shared_mem and omp.free_shared_mem . This is also done for top-level function llvm.alloca s used in the same way when the parent function is a target device function. This ensures that explicit private allocations, intended to be shared across threads, use the proper memory space on a target device while supporting the case of parallel regions indirectly reached from within a target region via function calls. **中文:** 本 Pass 将位于非 SPMD target region(target 区域)中、随后可能在 omp.parallel region(并行区域)内部被使用的 llvm.alloca 操作替换为 omp.alloc_shared_mem 和 omp.free_shared_mem 。当父函数是 target device 函数时,同样处理以相同方式使用的顶层函数的 llvm.alloca。这确保了那些本意要在多线程之间共享的显式私有分配,在 target device 上使用正确的 memory space(内存空间),同时支持从 target region 内部通过函数调用间接到达 parallel region 的情形。 --- ## 'shard' Dialect Passes('shard' 方言 Pass) ### -shard-partition **EN:** Partition a function into SPMD form. This pass fits in right after a pass that annotates the function with shardings like the ShardingPropagation pass. It operates on a fully annotated IR. A fully annotated IR required that all ranked tensor operands, results and block arguments are annotated with the shard.shard operation. **中文:** 将一个函数划分为 SPMD(单程序多数据)形式。此 Pass 紧跟在某个为函数添加分片(sharding)标注的 Pass 之后运行,例如 ShardingPropagation pass。它作用于一个完全标注好的 IR。所谓完全标注的 IR,要求所有带 rank 的张量操作数、结果和 block 参数都用 shard.shard 操作进行了标注。 **EN:** All direct descendant operations in the function must implement the ShardingInterface interface or all their ranked tensor operands and results must have full replication sharding. The input IR must have sharding annotations such that each operation that implements ShardingInterface can handle during partition with its partition method. This can be achieved with the ShardingPropagation pass. If the function has multiple terminating blocks, it is the responsibility of the the one who annotates the function with shardings to make sure that all returns would be consisted that is, have the same sharding. **中文:** 函数内所有直接的后代操作(descendant operations)必须实现 ShardingInterface 接口,或者它们所有带 rank 的张量操作数和结果都必须具有全复制(full replication)分片。输入 IR 必须带有分片标注,使得每个实现了 ShardingInterface 的操作都能在划分(partition)时通过其 partition 方法进行处理。这可以通过 ShardingPropagation pass 来实现。如果函数有多个终止 block(terminating blocks),那么由为函数添加分片标注的一方负责确保所有 return 都保持一致,即具有相同的分片。 **Example / 示例:** ```mlir shard.grid @grid_1d(shape = 2) func.func @f( %arg0: tensor<2xi8> ) -> tensor<2xi8> { %0 = shard.shard %arg0 to <@grid_1d, [[0]]> : tensor<2xi8> %1 = shard.shard %0 to <@grid_1d, [[0]]> annotate_for_users: tensor<2xi8> %2 = tosa.abs %1 : (tensor<2xi8>) -> tensor<2xi8> %3 = shard.shard %2 to <@grid_1d, [[0]]> : tensor<2xi8> %4 = shard.shard %3 to <@grid_1d, [[]]> annotate_for_users: tensor<2xi8> return %4 : tensor<2xi8> } ``` **EN:** Partitioning the above would result in Performing the element-wise abs operation on each device. Resharding to full replication with an all-gather. **中文:** 对上述代码进行划分(partition)后会得到如下结果:在每个设备上执行逐元素(element-wise)的 abs 运算,再通过 all-gather 重新分片为全复制(full replication)。 ```mlir shard.grid @grid_1d(shape = 2) func.func @f(%arg0: tensor<1xi8>) -> tensor<2xi8> { %0 = tosa.abs %arg0 : (tensor<1xi8>) -> tensor<1xi8> %1 = shard.all_gather %0 on @grid_1d grid_axes = [0] gather_axis = 0 : tensor<1xi8> -> tensor<2xi8> return %1 : tensor<2xi8> } ``` ### -shard-simplify **EN:** Shard simplify patterns. **中文:** Shard 简化模式。 **EN:** Applies simplification patterns on the Shard dialect operations. This includes: All-reduce endomorphism simplification, e.g. transforming all_reduce_sum(x) + all_reduce_sum(y) into all_reduce_sum(x + y) . **中文:** 对 Shard 方言的操作应用简化模式。其中包括:All-reduce 内同态(endomorphism)简化,例如将 all_reduce_sum(x) + all_reduce_sum(y) 转换为 all_reduce_sum(x + y)。 **EN:** Folding AllSliceOp(AllReduceOp) into ReduceScatterOp when both ops share the same grid and grid_axes. Folding static grid shapes into constants. **中文:** 当两个操作共享相同的 grid 和 grid_axes 时,将 AllSliceOp(AllReduceOp) 折叠(folding)为 ReduceScatterOp。将静态的 grid shape 折叠为常量。 ### -sharding-propagation **EN:** Sharding propagation **中文:** 分片传播 **EN:** Propagates sharding information throughout the graph. After this pass, each of the operations’ operands and results is annotated with a shard.shard operation, and the operations themselves are added with sharding option attributes. **中文:** 在整个图中传播分片信息。在此 Pass 之后,每个操作的操作数和结果都会用 shard.shard 操作进行标注,而操作本身也会被加上分片选项属性(sharding option attributes)。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-traversal` | Traversal order to use for sharding propagation: | 用于分片传播的遍历顺序: | --- ## ‘ml_program’ Dialect Passes(‘ml_program’ 方言 Pass) ### -mlprogram-pipeline-globals **EN:** Optimize ml_program global operations for read and store **中文:** 优化用于读取与存储的 ml_program 全局操作。 **EN:** ml_program’s load and store operations can be optimized for write-write or write-read sets of operations. This allows known tensors to not be re-read when the value is already known in IR. **中文:** ml_program 的 load(加载)和 store(存储)操作可以针对写-写或写-读的操作集合进行优化。这样,当某个值在 IR 中已经已知时,已知的张量(tensor)就不需要被重新读取。 **EN:** The pass is designed to handle both nested regions and function calls safely. **中文:** 该 Pass 被设计为能够安全地处理嵌套区域(nested regions)和函数调用。 --- ## ’nvgpu’ Dialect Passes(’nvgpu’ 方言 Pass) ### -nvgpu-optimize-shared-memory **EN:** Optimizes accesses to shard memory memrefs in order to reduce bank conflicts. **中文:** 优化对共享内存(shard memory)memref 的访问,以减少 bank conflict(存储体冲突)。 --- ## ’nvvm’ Dialect Passes('nvvm' 方言 Pass) ### -llvm-optimize-for-nvvm-target **EN:** Optimize NVVM IR **中文:** 优化 NVVM IR --- ## 'quant' Dialect Passes('quant' 方言 Pass) ### -lower-quant-ops **EN:** Lower quant.dcast and quant.qcast ops **中文:** 降低(lower)quant.dcast 与 quant.qcast op。 **EN:** Lower quantization ( quant.qcast ) and dequantization ( quant.dcast ) ops into other core dialects. The lowering process generates storage type casts in the form of quant.scast ops to act as an interface between the original quantized types of operands and results and their corresponding storage types used in the generated arithmetic computations. **中文:** 将量化(quant.qcast)与反量化(quant.dcast)op 降低到其它核心方言。该降低过程会生成以 quant.scast op 形式存在的存储类型转换(storage type cast),作为操作数与结果的原量化类型、以及所生成的算术运算中使用的对应存储类型之间的接口。 ### -normalize-quant-types **EN:** Normalize generic quantized types to specific quantized types **中文:** 将通用量化类型规范化为具体的量化类型。 **EN:** This pass converts generic quantized types in the quant dialect to more specific types when possible. The following conversions are performed: **中文:** 该 Pass 在可能的情况下,把 quant 方言中的通用量化类型转换为更具体的类型。执行以下转换: **EN:** 1. Sub-channel to per-axis: If the shape of the scales tensor of sub-channel quantized type has all but one non-one value, it is converted to a per-axis quantized type. For example: **中文:** 1. 子通道(sub-channel)到逐轴(per-axis):若子通道量化类型的 scales 张量的形状中除一个维度外均为非 1 值,则被转换为逐轴量化类型。例如: ```mlir !quant.uniform -> !quant.uniform tensor> -> tensor> ``` **EN:** 2. Sub-channel to per-tensor: If a sub-channel quantized type has only one scale or zero-point, it is converted to a per-tensor quantized type. For example: **中文:** 2. 子通道(sub-channel)到逐张量(per-tensor):若子通道量化类型只有一个 scale 或 zero-point,则被转换为逐张量量化类型。例如: ```mlir !quant.uniform -> !quant.uniform tensor> -> tensor> ``` **EN:** The rationale for these conversions is that the decompositions / handling of more precise quantized types tends to be more efficient than treating everything as subchannel type. **中文:** 进行这些转换的理由是:对更精确的量化类型做分解(decomposition)/处理,往往比把一切都当作子通道(subchannel)类型来处理更高效。 ### -strip-func-quant-types **EN:** Strip quantized types from function headers **中文:** 从函数头(function header)中剥离量化类型。 **EN:** Identify occurrences of function arguments using a quantized type and replace them with a new value of the corresponding storage (signless integer) type. For each converted argument, a quant.scast op is introduced at the head of the function’s entry block converting the new integer argument into the original quantized value. **中文:** 识别使用量化类型的函数形参出现的位置,并用一个对应存储类型(signless integer,即不带符号属性标注的整数类型)的新值来替换它们。对于每个被转换的形参,会在该函数入口块(entry block)的头部引入一个 quant.scast op,把新的整型形参转换为原来的量化值。 --- ## Reducer Passes(约简器 Pass) ### -opt-reduction-pass **EN:** A wrapper pass that reduces the file with optimization passes **中文:** 一个包装(wrapper)Pass,用于利用优化 Pass 对文件进行约减。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-opt-pass` | The optimization passes used for reduction, e.g., symbol-dce | 用于约简的优化 Pass,例如 `symbol-dce` | | `-opt-pass-file` | The file path containing the optimization pipeline definition | 包含优化流水线(pipeline)定义的文件路径 | | `-test` | The location of the tester which tests the file interestingness | 测试文件“有趣性”(interestingness)的测试器(tester)所在位置 | | `-test-arg` | arguments of the tester | 测试器的参数 | ### -reduction-tree **EN:** Reduce the input with reduction-tree algorithm **中文:** 使用 reduction-tree(约简树)算法对输入进行约减。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-traversal-mode` | The graph traversal mode, the default is single-path mode | 图遍历(traversal)模式,默认为单路径(single-path)模式 | | `-test` | The location of the tester which tests the file interestingness | 测试文件“有趣性”(interestingness)的测试器(tester)所在位置 | | `-test-arg` | arguments of the tester | 测试器的参数 | --- ## ‘scf’ Dialect Passes(‘scf’ 方言 Pass) ### -scf-for-loop-canonicalization **EN:** Canonicalize operations within scf.for loop bodies **中文:** 规范化(canonicalize)scf.for 循环体内的操作。 ### -scf-for-loop-peeling **EN:** Peel for loops at their upper bounds. **中文:** 在 for 循环的上界处将其剥离(peel)。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-peel-front` | Peel the first iteration out of the loop. | 将第一次迭代从循环中剥离出来。 | | `-skip-partial` | Do not peel loops inside of the last, partial iteration of another already peeled loop. | 不要剥离位于另一个已被剥离的循环的最后一次不完整(partial)迭代内部的循环。 | ### -scf-for-loop-range-folding **EN:** Fold add/mul ops into loop range **中文:** 将加法/乘法(add/mul)算子折叠(fold)进循环范围。 ### -scf-for-loop-specialization **EN:** Specialize for loops for vectorization **中文:** 为向量化(vectorization)对 for 循环进行特化(specialization)。 ### -scf-for-to-while **EN:** Convert SCF for loops to SCF while loops **中文:** 将 SCF for 循环转换为 SCF while 循环。 **EN:** This pass transforms SCF.ForOp operations to SCF.WhileOp. The For loop condition is placed in the ‘before’ region of the while operation, and the induction variable incrementation and loop body in the ‘after’ region. The loop carried values of the while op are the induction variable (IV) of the for-loop + any iter_args specified for the for-loop. Any ‘yield’ ops in the for-loop are rewritten to additionally yield the (incremented) induction variable. **中文:** 该 pass 将 SCF.ForOp 操作转换为 SCF.WhileOp。For 循环的条件被放入 while 操作的 ‘before’ region,而归纳变量(induction variable)的递增和循环体则放在 ‘after’ region。while op 携带的 loop-carried values 是 for 循环的归纳变量(IV),加上为 for 循环指定的任何 iter_args。for 循环中的任何 ‘yield’ op 都会被改写,使其额外 yield(产出)已递增后的归纳变量。 ```mlir scf.for %i = %c0 to %arg1 step %c1 { %0 = arith.addi %arg2, %arg2 : i32 memref.store %0, %arg0[%i] : memref } # After: %0 = scf.while (%i = %c0) : (index) -> index { %1 = arith.cmpi slt, %i, %arg1 : index scf.condition(%1) %i : index } do { ^bb0(%i: index): %1 = arith.addi %i, %c1 : index %2 = arith.addi %arg2, %arg2 : i32 memref.store %2, %arg0[%i] : memref scf.yield %1 : index } ``` ### -scf-forall-to-for **EN:** Convert SCF forall loops to SCF for loops **中文:** 将 SCF forall 循环转换为 SCF for 循环。 ### -scf-forall-to-parallel **EN:** Convert SCF forall loops to SCF parallel loops **中文:** 将 SCF forall 循环转换为 SCF parallel 循环。 ### -scf-parallel-for-to-nested-fors **EN:** Convert SCF parallel for loops to nested SCF for loops **中文:** 将 SCF parallel for 循环转换为嵌套的 SCF for 循环。 **EN:** This pass transforms SCF::ParallelOp operations into a nest of SCF::ForOp operations. The transformation is useful for cases where the parallel loop can be expressed as a series of sequential iterations, allowing for more fine-grained control over the loop execution. **中文:** 该 pass 将 SCF::ParallelOp 操作转换为一组嵌套的 SCF::ForOp 操作。当并行循环可以表示为一系列顺序迭代时,这一变换很有用,从而允许对循环的执行进行更细粒度的控制。 ### -scf-parallel-loop-fusion **EN:** Fuse adjacent parallel loops **中文:** 融合(fuse)相邻的 parallel 循环。 ### -scf-parallel-loop-specialization **EN:** Specialize parallel loops for vectorization **中文:** 为向量化(vectorization)对 parallel 循环进行特化(specialization)。 ### -scf-parallel-loop-tiling **EN:** Tile parallel loops **中文:** 对 parallel 循环进行分块(tile / tiling)。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-parallel-loop-tile-sizes` | Factors to tile parallel loops by | 用于对 parallel 循环进行分块的因子。 | | `-no-min-max-bounds` | Perform tiling with fixed upper bound with inbound check inside the internal loops | 以固定的上界执行分块,并在内部(internal)循环中放入界检查(inbound check)。 | ### -test-scf-parallel-loop-collapsing **EN:** Test parallel loops collapsing transformation **中文:** 测试 parallel 循环折叠(collapsing)变换。 **EN:** This pass is purely for testing the scf::collapseParallelLoops transformation. The transformation does not have opinions on how a parallel loop should be collapsed, so this pass is structured for the common case on GPUs of collapsing to a 3d parallel loop. 3 lists can be provided to collapsed-indices-{0,1,2} to represent how the loop should be collapsed and must reference evrey iterator in the original parallel loop. **中文:** 该 pass 纯粹用于测试 scf::collapseParallelLoops 变换。这一变换本身对 parallel 循环应当如何折叠没有固定意见,因此本 pass 面向 GPU 上的一种常见情形来组织:将循环折叠为三维(3d)parallel 循环。可以为 collapsed-indices-{0,1,2} 提供 3 个列表来表示循环应如何折叠,并且必须引用原始 parallel 循环中的每一个迭代器(iterator)。 ```mlir scf.parallel (%arg0, %arg1) = (%c0, %c0) to (%c2, %c2) step (%c1, %c1) { "test.sink"(%5, %3) : (index, index) -> () scf.yield } # After: scf.parallel (%arg0) = (%c0) to (%c4) step (%c1) { %0 = arith.remsi %arg0, %c2 : index %1 = arith.divsi %arg0, %c2 : index %2 = arith.muli %0, %c7 : index %3 = arith.addi %2, %c3 : index %4 = arith.muli %1, %c7 : index %5 = arith.addi %4, %c3 : index "test.sink"(%5, %3) : (index, index) -> () } ``` **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-collapsed-indices-0` | Which loop indices to combine 0th loop index | 要合并进第 0 个循环索引的循环索引。 | | `-collapsed-indices-1` | Which loop indices to combine into the position 1 loop index | 要合并进位置 1 的循环索引的循环索引。 | | `-collapsed-indices-2` | Which loop indices to combine into the position 2 loop index | 要合并进位置 2 的循环索引的循环索引。 | --- ## ‘shape’ Dialect Passes(‘shape’ 方言 Pass) ### -outline-shape-computation **EN:** Using shape.func to preserve shape computation This pass outlines the shape computation part in high level IR by adding shape.func and populate corresponding mapping information into ShapeMappingAnalysis. The shape computation part is usually introduced by shape reification, and each single dynamic shape is denoted by shape.with_shape. **中文:** 使用 shape.func 来保留形状(shape)计算。该 Pass 通过在高层 IR 中添加 shape.func、把其中的形状计算部分抽取(outline)出来,并将对应的映射信息填充到 ShapeMappingAnalysis 中。形状计算部分通常由 shape reification(形状实体化)引入,而每一个动态形状都由 shape.with_shape 来表示。 **EN:** There’re two main reasons this shape-outline pass is needed: 1. Many passes don’t take shape reification part into consideration. Therefore we need to “remove” the shape reification part temporarily for these passes. 2. Sometimes we cannot redo shape reification after converting from dialect A to dialect B. Because op-level shape reification is only implemented on A. **中文:** 之所以需要这个 shape-outline(形状抽取)Pass,主要有两个原因: 1. 许多 Pass 并不会把 shape reification(形状实体化)部分考虑在内。因此我们需要为这些 Pass 暂时“移除”形状实体化部分。 2. 有时在从方言 A 转换到方言 B 之后,我们无法重新执行 shape reification。因为 op 级别的 shape reification 只在 A 上实现了。 **Input / 输入:** ```mlir func.func @main(%arg0: tensor, %arg1: tensor<2x4x?xf32>) -> tensor { %c2 = arith.constant 2 : index %c0 = arith.constant 0 : index %c4 = arith.constant 4 : index %0 = shape.shape_of %arg0 : tensor -> tensor<3xindex> %1 = shape.get_extent %0, %c2 : tensor<3xindex>, index -> index %2 = "test.abs"(%arg0) : (tensor) -> tensor %3 = shape.with_shape %2, %0 : tensor, tensor<3xindex> %4 = shape.value_of %3 : tensor %5 = "test.concat"(%4, %arg1) {axis = 0 : i64} : (tensor, tensor<2x4x?xf32>) -> tensor %6 = shape.get_extent %0, %c0 : tensor<3xindex>, index -> index %7 = arith.addi %6, %c2 : index %8 = shape.from_extents %7, %c4, %1 : index, index, index %9 = shape.with_shape %5, %8 : tensor, !shape.shape %10 = shape.value_of %9 : tensor return %10 : tensor } ``` **Output / 输出:** ```mlir func.func @main(%arg0: tensor, %arg1: tensor<2x4x?xf32>) -> tensor { %0 = "test.abs"(%arg0) : (tensor) -> tensor %1 = "test.concat"(%0, %arg1) {axis = 0 : i64} : (tensor, tensor<2x4x?xf32>) -> tensor return %1 : tensor } shape.func private @shape_cal_1(%arg0: tensor) -> !shape.shape { %c2 = arith.constant 2 : index %c0 = arith.constant 0 : index %c4 = arith.constant 4 : index %0 = shape_of %arg0 : tensor -> tensor<3xindex> %1 = get_extent %0, %c2 : tensor<3xindex>, index -> index %2 = get_extent %0, %c0 : tensor<3xindex>, index -> index %3 = arith.addi %2, %c2 : index %4 = from_extents %3, %c4, %1 : index, index, index return %4 : !shape.shape } shape.func private @shape_cal_0(%arg0: tensor) -> tensor<3xindex> { %0 = shape_of %arg0 : tensor -> tensor<3xindex> return %0 : tensor<3xindex> } ``` **EN:** For the above example, the shape computation is inlined in the input IR, which is used for two values’ (test.abs and test.concat) shape. And the shape computation part is outlined in the output IR. And the shape mapping information will be: **中文:** 对于上面的例子,形状计算在输入 IR 中是内联(inline)的,它被用于两个值(test.abs 和 test.concat)的形状。而在输出 IR 中,形状计算部分被抽取(outline)了出来。 其形状映射信息将如下所示: ```mlir // ---- Shape Mapping Information ----// - Shape for: %0 = "test.abs"(%arg0) : (tensor) -> tensor :: @shape_cal_0( of type 'tensor' at index: 0) // - Shape for: %1 = "test.concat"(%0, %arg1) {axis = 0 : i64} : (tensor, tensor<2x4x?xf32>) -> tensor :: @shape_cal_1( of type 'tensor' at index: 0) ``` ### -remove-shape-constraints **EN:** Replace all cstr ops with a true witness_ **中文:** 将所有 cstr op 替换为一个恒真(true)的见证值(witness)。 ### -shape-to-shape-lowering **EN:** Legalize Shape dialect to be convertible to Arith **中文:** 将 Shape 方言合法化,使其可转换为 Arith。 --- ## ‘sparse_tensor’ Dialect Passes(‘sparse_tensor’ 方言 Pass) ### -lower-sparse-foreach-to-scf **EN:** Decompose a complex sparse operation into multiple stages **中文:** 将一个复杂的稀疏算子分解为多个阶段。 **EN:** A pass that lowers sparse_tensor.foreach operation to scf dialect. **中文:** 将 `sparse_tensor.foreach` 操作降级(lower)到 scf 方言的 Pass。 ### -lower-sparse-iteration-to-scf **EN:** Lower sparse_tensor.iterate/coiterate into scf loops **中文:** 将 sparse_tensor.iterate/coiterate 降级为 scf 循环 **EN:** This pass lowers sparse_tensor.iterate operations into scf.for/while operations. The pass is not yet stabilized. **中文:** 该 Pass 将 `sparse_tensor.iterate` 操作降级为 `scf.for`/`while` 操作。该 Pass 尚未稳定(not yet stabilized)。 ### -lower-sparse-ops-to-foreach **EN:** Applies sparse tensor rewriting rules after sparsification **中文:** 在稀疏化(sparsification)之后应用稀疏张量重写规则 **EN:** A pass that lowers high-level sparse operations to sparse_tensor.foreach. **中文:** 将高层稀疏算子降级为 `sparse_tensor.foreach` 的 Pass。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-enable-runtime-library` | Enable runtime library for manipulating sparse tensors | 启用用于操作稀疏张量的运行时库(runtime library) | | `-enable-convert` | Enable rewriting rules for the convert operator | 启用 convert 算子的重写规则 | ### -pre-sparsification-rewrite **EN:** Applies sparse tensor rewriting rules prior to sparsification **中文:** 在稀疏化之前应用稀疏张量重写规则 **EN:** A pass that applies rewriting rules to sparse tensor operations prior to running the actual sparsification pass. **中文:** 在实际运行稀疏化(sparsification)Pass 之前,对稀疏张量操作应用重写规则的 Pass。 ### -sparse-assembler **EN:** Add [dis]assemble operations on external sparse tensors **中文:** 在外部稀疏张量上添加组装/拆解([dis]assemble)算子 **EN:** Unlike dense tensors, MLIR does not provide a direct _mlir_ciface_ ABI for passing sparse tensors as arguments from and to external methods (within MLIR-generated methods, sparse tensors can be freely passed around, but this eventually uses a bespoke parameter passing format that is subject to change; like opaque pointers when the sparse runtime support library is used or the constituent arrays and structs for direct IR codegen). The sparse assembler pass, however, can be used to obtain a stable _mlir_ciface_ API for passing sparse tensors from and to an external environment, such as Python, PyTorch, or JAX. **中文:** 与稠密(dense)张量不同,MLIR 没有提供直接的 _mlir_ciface_ ABI 来从外部方法传入或传出稀疏张量作为参数(在 MLIR 生成的方法内部,稀疏张量可以自由传递,但这最终使用的是一种专门的、可能随时变更的参数传递格式;例如使用稀疏运行时支持库时的 opaque pointers(不透明指针),或直接 IR codegen 时的构成数组和结构体)。然而,sparse assembler pass 可用于获得稳定的 _mlir_ciface_ API,以便在外部环境(如 Python、PyTorch 或 JAX)与程序之间传递稀疏张量。 **EN:** The pass converts public entry methods that use sparse tensors as input parameters and/or output return values into wrapper methods that [dis]assemble the individual tensors that constitute the actual storage used externally into MLIR sparse tensors. This pass can be used to prepare the public entry methods of a program that is compiled by the MLIR sparsifier to interface with an external runtime, e.g., when passing sparse tensors as numpy arrays from and to Python. Note that eventual bufferization decisions (e.g. who [de]allocates the underlying memory) should be resolved in agreement with the external runtime. **中文:** 该 Pass 将使用稀疏张量作为输入参数和/或输出返回值的公开入口方法转换为包装方法,这些包装方法会将构成外部实际存储的各个张量[解/组]装为 MLIR 稀疏张量。当程序由 MLIR sparsifier(稀疏化器)编译时,可以用该 Pass 来准备程序的公开入口方法,以便与外部运行时(runtime)交互,例如在 Python 之间以 numpy 数组的形式传入传出稀疏张量。注意,最终的 bufferization(缓冲化)决策(例如由谁[解/分]配底层内存)应与外部运行时协商一致。 **EN:** By default, the pass uses the [dis]assemble operations to input and output sparse tensors. When the direct-out option is set, however, the output directly returns the MLIR allocated buffers to the external runtime. **中文:** 默认情况下,该 Pass 使用 [dis]assemble 算子来输入和输出稀疏张量;但当设置了 `direct-out` 选项时,输出会直接将 MLIR 分配的缓冲区返回给外部运行时。 **EN:** The pass should always run before the actual sparsification passes. **中文:** 该 Pass 应始终在实际的稀疏化(sparsification)Pass 之前运行。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-direct-out` | Directly returns buffers externally | 直接将缓冲区返回给外部 | ### -sparse-buffer-rewrite **EN:** Rewrite sparse primitives on buffers to actual code **中文:** 将缓冲区上的稀疏原语(primitives)重写为实际代码 **EN:** A pass that rewrites sparse primitives on buffers to the MLIR implementation of the primitives. For example, sparse_tensor.sort operator is implemented in this pass. **中文:** 将缓冲区上的稀疏原语重写为其 MLIR 实现的 Pass。例如,`sparse_tensor.sort` 算子就实现在该 Pass 中。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-enable-buffer-initialization` | Enable zero-initialization of the memory buffers | 启用内存缓冲区的零初始化 | ### -sparse-gpu-codegen **EN:** Generates GPU code during sparsification **中文:** 在稀疏化期间生成 GPU 代码 **EN:** Enables the sparsifier to use GPU acceleration. When the number of GPU threads is set to zero, the pass tries to enable GPU acceleration by means of direct library calls (like cuSPARSE). **中文:** 使稀疏化器(sparsifier)能够使用 GPU 加速。当 GPU 线程数设置为零时,该 Pass 会尝试通过直接库调用(如 cuSPARSE)来启用 GPU 加速。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-num-threads` | Sets the number of GPU threads | 设置 GPU 线程数 | | `-enable-runtime-library` | Enable runtime library for manipulating sparse tensors | 启用用于操作稀疏张量的运行时库(runtime library) | ### -sparse-reinterpret-map **EN:** Reinterprets sparse tensor type mappings **中文:** 重新解释稀疏张量类型映射(mappings) **EN:** A pass that reinterprets the mappings in all sparse tensor types in a way that enables subsequent sparsification. This involves expressing all linalg.generic operations in terms of level coordinates (rather than the dimension coordinates of the input tensors) to align the iteration space with the potentially remapped level space as well as resolving cycles in the resulting iteration graphs with explicit sparse tensor conversions where needed. **中文:** 以支持后续稀疏化的方式,重新解释所有稀疏张量类型中的映射(mappings)的 Pass。这包括将所有 `linalg.generic` 操作用 level coordinates(层级坐标)来表达(而不是输入张量的维度坐标),以使迭代空间与可能被重映射的层级空间对齐;并在必要时用显式的稀疏张量转换来消除由此产生的迭代图中的环(cycles)。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-scope` | Set the reiterpretation scope | 设置重新解释的作用范围(scope) | | `-loop-ordering-strategy` | Set the loop ordering strategy for sparse code generation | 设置稀疏代码生成的循环排序策略(loop ordering strategy) | ### -sparse-space-collapse **EN:** Sparse space collapsing pass **中文:** 稀疏空间折叠 Pass **EN:** This pass collapses consecutive sparse spaces (extracted from the same tensor) into one multi-dimensional space. The pass is not yet stabilized. **中文:** 该 Pass 将连续的稀疏空间(从同一张量中提取)折叠为一个多维空间。该 Pass 尚未稳定。 ### -sparse-storage-specifier-to-llvm **EN:** Lower sparse storage specifer to llvm structure **中文:** 将稀疏存储描述符(storage specifier,原文拼写为 specifer)降级为 LLVM 结构体 **EN:** This pass rewrites sparse tensor storage specifier-related operations into LLVMDialect, and converts sparse tensor storage specifier into an llvm.struct. **中文:** 该 Pass 将稀疏张量存储描述符(storage specifier)相关的操作重写为 LLVMDialect,并将稀疏张量存储描述符转换为 `llvm.struct`。 **Example of the conversion / 转换示例:** **Before / 之前:** ```mlir %0 = sparse_tensor.storage_specifier.get %arg0 dim_sz at 0 : !sparse_tensor.storage_specifier<#CSR> to i64 ``` **After / 之后:** ```mlir %0 = llvm.extractvalue %arg0[0, 0] : !llvm.struct<(array<2 x i64>, array<3 x i64>)> ``` ### -sparse-tensor-codegen **EN:** Convert sparse tensors and primitives to actual code **中文:** 将稀疏张量和原语转换为实际代码 **EN:** A pass that converts sparse tensor types and primitives to actual compiler visible buffers and compiler IR that implements these primitives on the selected sparse tensor storage schemes. **中文:** 将稀疏张量类型和原语(primitives)转换为编译器可见的实际缓冲区、以及基于所选稀疏张量存储方案实现这些原语的编译器 IR 的 Pass。 **EN:** This pass provides an alternative to the SparseTensorConversion pass, eliminating the dependence on a runtime support library, and providing much more opportunities for subsequent compiler optimization of the generated code. **中文:** 该 Pass 为 SparseTensorConversion pass 提供了一种替代方案,消除了对运行时支持库的依赖,并为后续编译器优化生成的代码提供更多机会。 **Example of the conversion / 转换示例:** **Before / 之前:** ```mlir func.func @foo(%arg0: tensor<8x8xf32, #CSR>) -> memref { %0 = sparse_tensor.positions %arg0 {level = 1 : index} : tensor<8x8xf32, #CSR> to memref return %0 : memref } ``` **After / 之后:** ```mlir func.func @foo(%arg0: memref, %arg1: memref, %arg2: memref, %arg3: !sparse_tensor.storage_specifier<#sparse>) -> memref { %0 = sparse_tensor.storage_specifier.get %arg3 pos_mem_sz at 1 : !sparse_tensor.storage_specifier<#sparse> %subview = memref.subview %arg0[0] [%0] [1] : memref to memref return %subview : memref } ``` **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-enable-buffer-initialization` | Enable zero-initialization of the memory buffers | 启用内存缓冲区的零初始化 | | `-create-sparse-deallocs` | Specify if the temporary buffers created by the sparse compiler should be deallocated. For compatibility with core bufferization passes. This option is only used when enable-runtime-library=false. See also create-deallocs for BufferizationOption. | 指定由稀疏编译器创建的临时缓冲区是否应被释放(deallocate)。用于与核心 bufferization pass 保持兼容。该选项仅在 `enable-runtime-library=false` 时使用。另见 BufferizationOption 的 `create-deallocs`。 | ### -sparse-tensor-conversion **EN:** Convert sparse tensors and primitives to library calls **中文:** 将稀疏张量和原语转换为库调用 **EN:** A pass that converts sparse tensor primitives into calls into a runtime support library. Sparse tensor types are converted into opaque pointers to the underlying sparse storage schemes. **中文:** 将稀疏张量原语(primitives)转换为对运行时支持库调用的 Pass。稀疏张量类型被转换为指向底层稀疏存储方案的 opaque pointer(不透明指针)。 **EN:** The use of opaque pointers together with runtime support library keeps the conversion relatively simple, but at the expense of IR opacity, which obscures opportunities for subsequent optimization of the IR. An alternative is provided by the SparseTensorCodegen pass. **中文:** 使用 opaque pointers 配合运行时支持库使转换相对简单,但代价是 IR 的不透明性(opacity),这掩盖了对 IR 进行后续优化的机会。SparseTensorCodegen pass 提供了一种替代方案。 **Example of the conversion / 转换示例:** **Before / 之前:** ```mlir func.func @foo(%arg0: tensor<8x8xf32, #CSR>) -> memref { %0 = sparse_tensor.positions %arg0 {level = 1 : index} : tensor<8x8xf32, #CSR> to memref return %0 : memref } ``` **After / 之后:** ```mlir func.func @foo(%arg0: !llvm.ptr) -> memref { %c1 = arith.constant 1 : index %0 = call @sparsePositions0(%arg0, %c1) : (!llvm.ptr, index) -> memref return %0 : memref } ``` ### -sparse-vectorization **EN:** Vectorizes loops after sparsification **中文:** 在稀疏化之后向量化循环 **EN:** A pass that converts loops after sparsification into vector loops. The vector dialect is used as target to provide an architectural neutral way of exploiting any platform that supports SIMD instructions. **中文:** 将稀疏化之后的循环转换为向量循环的 Pass。以 vector 方言作为目标,以架构中立的方式利用任何支持 SIMD 指令的平台。 **EN:** The vector length (viz. vl ) describes the number of packed data elements (e.g. both vector<16xf32> and vector<16xf64> have a vector length of 16 even though the actual bitwidths differ). A small multiple of the actual lengths supported in hardware typically results in efficient SIMD code, since the backend will map longer vectors to multiple vector registers, thereby effectively unrolling an addition level within the generated for-loop. **中文:** 向量长度(即 `vl`)描述打包数据元素的个数(例如 `vector<16xf32>` 和 `vector<16xf64>` 的向量长度都是 16,尽管实际位宽不同)。硬件所支持的实际长度的一个小倍数通常能产生高效的 SIMD 代码,因为后端会把更长的向量映射到多个向量寄存器中,从而在生成的 for 循环内有效地多展开一层。 **Example of the conversion / 转换示例:** **Before / 之前:** ```mlir %3 = memref.load %2[] : memref %4 = scf.for %arg3 = %c0 to %c1024 step %c1 iter_args(%arg4 = %3) -> (f32) { %6 = memref.load %0[%arg3] : memref %7 = memref.load %1[%arg3] : memref<1024xf32> %8 = arith.mulf %6, %7 : f32 %9 = arith.addf %arg4, %8 : f32 scf.yield %9 : f32 } memref.store %4, %2[] : memref ``` **After / 之后:** ```mlir %3 = memref.load %2[] : memref %4 = vector.insert %3, %cst [0] : f32 into vector<32xf32> %5 = scf.for %arg3 = %c0 to %c1024 step %c32 iter_args(%arg4 = %4) -> (vector<32xf32>) { %8 = vector.load %0[%arg3] : memref, vector<32xf32> %9 = vector.load %1[%arg3] : memref<1024xf32>, vector<32xf32> %10 = arith.mulf %8, %9 : vector<32xf32> %11 = arith.addf %arg4, %10 : vector<32xf32> scf.yield %11 : vector<32xf32> } %6 = vector.reduction , %5 : vector<32xf32> into f32 memref.store %6, %2[] : memref ``` **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-vl` | Set the vector length (use 0 to disable vectorization) | 设置向量长度(使用 0 以禁用向量化) | | `-enable-vla-vectorization` | Enable vector length agnostic vectorization | 启用与向量长度无关的向量化(vector length agnostic vectorization) | | `-enable-simd-index32` | Enable i32 indexing into vectors (for efficient gather/scatter) | 启用对向量的 i32 索引(用于高效的 gather/scatter) | ### -sparsification **EN:** Automatically generate sparse tensor code from sparse tensor types **中文:** 从稀疏张量类型自动生成稀疏张量代码 **EN:** A pass that implements the core functionality of a sparsifier. Each Linalg operation (MLIR’s tensor index notation) that operates on sparse tensor types is converted into code in which the sparsity is explicit both in terms of co-iterating looping logic as well as selected sparse storage schemes. **中文:** 实现稀疏化器(sparsifier)核心功能的 Pass。每个作用于稀疏张量类型的 Linalg 操作(MLIR 的张量索引记法)都被转换为显式表达稀疏性的代码,这既体现在共迭代(co-iterating)循环逻辑上,也体现在所选的稀疏存储方案上。 **EN:** See the SparseTensor dialect documentation for more background. **中文:** 更多背景请参见 SparseTensor 方言文档。 **Example input / 输入示例:** ```mlir #matvec = { indexing_maps = [ affine_map<(i,j) -> (i,j)>, // A affine_map<(i,j) -> (j)>, // b affine_map<(i,j) -> (i)> // x (out) ], iterator_types = ["parallel", "reduction"], doc = "X(i) += A(i,j) * B(j)" } // Multiply a sparse matrix A with a dense vector b into a dense vector x. func.func @kernel_matvec(%arga: tensor, %argb: tensor, %argx: tensor) -> tensor { %0 = linalg.generic #matvec ins(%arga, %argb: tensor, tensor) outs(%argx: tensor) { ^bb(%a: f64, %b: f64, %x: f64): %0 = arith.mulf %a, %b : f64 %1 = arith.addf %x, %0 : f64 linalg.yield %1 : f64 } -> tensor return %0 : tensor } ``` **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-parallelization-strategy` | Set the parallelization strategy | 设置并行化策略(parallelization strategy) | | `-sparse-emit-strategy` | Emit functional code or interfaces (to debug) for sparse loops | 为稀疏循环生成函数式代码或接口(用于调试) | | `-enable-runtime-library` | Enable runtime library for manipulating sparse tensors | 启用用于操作稀疏张量的运行时库(runtime library) | --- ### -sparsification-and-bufferization **EN:** Mini-pipeline that combines bufferization and sparsifiation **中文:** 一个组合了 bufferization(缓冲化)与 sparsification(稀疏化)的 mini-pipeline。 **EN:** This pass forms a mini-pipeline that combines bufferization and sparsifiation. **中文:** 本 pass 构成一个同时执行 bufferization(缓冲化)与 sparsification(稀疏化)的 mini-pipeline。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-vl` | Set the vector length (use 0 to disable vectorization) | 设置向量长度(设为 0 以禁用向量化) | | `-enable-vla-vectorization` | Enable vector length agnostic vectorization | 启用向量长度无关(vector length agnostic, VLA)的向量化 | | `-enable-simd-index32` | Enable i32 indexing into vectors (for efficient gather/scatter) | 启用对向量的 i32 索引(用于高效的 gather/scatter) | | `-enable-gpu-libgen` | Enable GPU acceleration by means of direct library calls | 通过直接库调用方式启用 GPU 加速 | | `-sparse-emit-strategy` | Emit functional code or interfaces (to debug) for sparse loops | 为稀疏循环发射(emit)功能代码或接口(用于调试) | | `-parallelization-strategy` | Set the parallelization strategy | 设置并行化策略 | ### -stage-sparse-ops **EN:** Decompose a complex sparse operation into multiple stages **中文:** 将一个复杂的稀疏操作分解为多个阶段(stage)。 **EN:** A pass that decomposes a complex sparse operation into multiple stages. E.g., CSR -> CSC is staged into CSR > COO (unordered) -> sort -> CSC. **中文:** 一个将复杂稀疏操作分解为多个阶段的 pass。例如,CSR -> CSC 被分阶段处理为 CSR > COO(无序)-> sort(排序)-> CSC。 --- ## ‘spv’ Dialect Passes(‘spv’ 方言 Pass) ### -decorate-spirv-composite-type-layout **EN:** Decorate SPIR-V composite type with layout info **中文:** 为 SPIR-V 复合类型添加布局(layout)信息 **EN:** Module pass that converts composite types used by objects in the StorageBuffer, PhysicalStorageBuffer, Uniform, and PushConstant storage classes to attatch layout information. Right now this pass only supports Vulkan layout rules. **中文:** 模块级 pass,将用于 StorageBuffer、PhysicalStorageBuffer、Uniform 和 PushConstant 存储类中对象的复合类型转换为附带布局(layout)信息的类型。目前该 pass 仅支持 Vulkan 布局规则。 ### -spirv-canonicalize-gl **EN:** Canonicalize GLSL ops **中文:** 规范化 GLSL op **EN:** Pass to run canoncalization patterns that involve GL ops. These patterns cannot be run in default canonicalization because GL ops aren’t always available. So they should be involed specifically when needed. **中文:** 运行涉及 GL op 的规范化(canonicalization)模式的 pass。由于 GL op 并不总是可用,这些模式无法在默认规范化中运行,因此应在需要时专门调用它们。 ### -spirv-lower-abi-attrs **EN:** Lower SPIR-V ABI attributes to global variables and entry points **中文:** 将 SPIR-V ABI 属性降级(lower)为全局变量和入口点 **EN:** Operation pass that lowers the ABI attributes specified during SPIR-V Lowering. Specifically: 1. Creates the global variables for arguments of entry point function using the specification in the spirv.interface_var_abi attribute for each argument. 2. Inserts the EntryPointOp and the ExecutionModeOp for entry point functions using the specification in the spirv.entry_point_abi attribute. **中文:** 将 SPIR-V Lowering 期间指定的 ABI 属性降级为全局变量和入口点的 op pass。具体而言: 1. 使用每个参数在 `spirv.interface_var_abi` 属性中的规范,为入口点函数的参数创建全局变量。 2. 使用 `spirv.entry_point_abi` 属性中的规范,为入口点函数插入 EntryPointOp 和 ExecutionModeOp。 ### -spirv-promote-to-replicated-constants **EN:** Convert splat composite constants and spec constants to corresponding replicated constant composite ops defined by SPV_EXT_replicated_composites **中文:** 将 splat 复合常量和 spec 常量转换为由 `SPV_EXT_replicated_composites` 定义的相应 replicated(复制)常量复合 op ### -spirv-rewrite-inserts **EN:** Rewrite sequential chains of spirv.CompositeInsert operations into spirv.CompositeConstruct operations **中文:** 将连续的 `spirv.CompositeInsert` op 链重写为 `spirv.CompositeConstruct` op ### -spirv-unify-aliased-resource **EN:** Unify access of multiple aliased resources into access of one single resource **中文:** 将多个别名(aliased)资源的访问统一为对单一资源的访问 ### -spirv-update-vce **EN:** Deduce and attach minimal (version, capabilities, extensions) requirements to spirv.module ops **中文:** 推导并将最小的(版本、capabilities、extensions)需求附加到 `spirv.module` op 上 **EN:** Operation pass that deduces and attaches the minimal version/ capabilities/extensions requirements for spirv.module ops. For each spirv.module op, this pass requires a spirv.target_env attribute on it or an enclosing module-like op to drive the deduction. The reason is that an op can be enabled by multiple extensions/capabilities. So we need to know which one to pick. spirv.target_env gives the hard limit as for what the target environment can support; this pass deduces what are actually needed for a specific spirv.module op. **中文:** 推导并为 `spirv.module` op 附加最小的 version / capabilities / extensions 需求的 op pass。对于每个 `spirv.module` op,该 pass 要求其自身或一个包围它的 module-like(模块状)op 上带有 `spirv.target_env` 属性来驱动推导。原因在于一个 op 可被多个 extension / capability 启用,因此我们需要知道应选择哪一个。`spirv.target_env` 给出目标环境所能支持的上限(hard limit),而该 pass 推导的是某个特定 `spirv.module` op 实际所需的内容。 ### -spirv-webgpu-prepare **EN:** Prepare SPIR-V to target WebGPU by expanding unsupported ops and replacing with supported ones **中文:** 通过展开不支持的 op 并替换为支持的 op,来准备面向 WebGPU 的 SPIR-V --- ## ’tensor’ Dialect Passes('tensor' 方言 Pass) ### -fold-tensor-subset-ops **EN:** Fold tensor subset ops into producer/consumer ops The pass folds tensor subset ops into producer/consumer ops. At the moment, the following foldings occur when possible: - tensor.extract_slice into vector.transfer_read - vector.transfer_write into tensor.insert_slice **中文:** 将张量子集 op 折叠到生产者/消费者 op 中 该 Pass 会将张量子集(tensor subset)op 折叠到其生产者/消费者 op 中。目前,在可行的情况下会发生以下折叠: - `tensor.extract_slice` 折叠为 `vector.transfer_read` - `vector.transfer_write` 折叠为 `tensor.insert_slice` ### -scalarize-single-element-tensor-return **EN:** Scalarize private functions that return single-element tensor Rewrites private functions returning exactly one statically shaped ranked tensor of exactly one element into functions returning the tensor element type, provided all transitive users can be updated safely. **中文:** 标量化(scalarize)返回单元素张量的私有函数 将「返回恰好一个静态形状、有秩(ranked)、且仅含一个元素的张量」的私有函数,重写为返回该张量元素类型的函数;前提是所有传递性使用方(transitive users)都能被安全地更新。 --- ## 'transform' Dialect Passes('transform' 方言 Pass) ### -transform-dialect-check-uses **EN:** Warn about potential use-after-free in the transform dialect **中文:** 警告 transform 方言中潜在的释放后使用(use-after-free)问题。 **EN:** This pass analyzes operations from the transform dialect and its extensions and warns if a transform IR value may be used by an operation after it was "freed" by some other operation, as described by side effects on the TransformMappingResource. This statically detects situations that lead to errors when interpreting the Transform IR. **中文:** 该 pass 分析来自 transform 方言及其扩展的操作,并在某个 transform IR 值可能已被其他操作"释放"(free)后仍被使用时发出警告,如 `TransformMappingResource` 上的副作用所描述的那样。该 pass 静态检测在解释执行 Transform IR 时会引发错误的情况。 **EN:** The pass is capable of handling branching control flow and reports all potential use-after-free situations, e.g., a may-use-after-free is reported if at least one of the control flow paths between the definition of a value and its use contains an operation with a "free" effect on the TransformMappingResource. It does not currently perform an SCCP-style data flow analysis to prove that some branches are not taken, however, SCCP and other control flow simplifications can be performed on the transform IR prior to this pass provided that transform ops implement the relevant control flow interfaces. **中文:** 该 pass 能够处理分支控制流并报告所有潜在的释放后使用情况,例如:如果值的定义与其使用之间至少一条控制流路径上存在对 `TransformMappingResource` 具有"free"效果的操作,则报告可能发生的释放后使用(may-use-after-free)。它目前不执行 SCCP 风格的数据流分析来证明某些分支不会被执行;不过,前提是 transform 操作实现了相关的控制流接口,可以在该 pass 之前对 transform IR 进行 SCCP 及其他控制流简化。 ### -transform-infer-effects **EN:** Infer transform side effects for symbols **中文:** 为符号推断 transform 副作用。 **EN:** This pass analyzes the definitions of transform dialect callable symbol operations, such as `transform.named_sequence`, and annotates the symbol arguments with attributes indicating the side effects that the nested operations have on them. **中文:** 该 pass 分析 transform 方言中可调用符号操作的定义(如 `transform.named_sequence`),并为符号参数添加属性,以指示嵌套操作对其产生的副作用。 ### -transform-interpreter **EN:** Transform dialect interpreter **中文:** Transform 方言解释器。 **EN:** This pass runs the transform dialect interpreter and applies the named sequence transformation specified by the provided name (defaults to `TransformDialect::kTransformEntryPointSymbolName`, i.e. `__transform_main`). **中文:** 该 pass 运行 transform 方言解释器,并应用由所提供名称指定的命名序列变换(默认为 `TransformDialect::kTransformEntryPointSymbolName`,即 `__transform_main`)。 **EN:** Additional options can be used to narrow down the pass applicability for debugging purposes: - `debugPayloadRootTag` makes the transform script apply to the payload operation that has a `transform.target_tag` string attribute with the given value, rather than to the anchor operation of the pass. - `debugBindTrailingArgs` allows one to bind values to trailing arguments of the transform entry point as follows: - arguments of `TransformHandleTypeInterface` type can be bound to all payload operations with the name provided as a simple string; - arguments of `TransformValueHandleTypeInterface` type can be bound to a flattened list of results of all operations with the name provided as a string prefixed with `^`; - arguments of `TransformParamTypeInterface` type can be bound to integer constants provided as `;` separated list prefixed with `#`. - `entryPoint` specifies the name of the transform symbol to serve as the entry point. **中文:** 可用于调试目的、缩小 pass 适用范围的附加选项: - `debugPayloadRootTag` 使 transform 脚本应用于具有指定值的 `transform.target_tag` 字符串属性的 payload 操作,而非该 pass 的锚定(anchor)操作。 - `debugBindTrailingArgs` 允许将值绑定到 transform 入口点的尾部参数,具体如下: - `TransformHandleTypeInterface` 类型的参数可绑定到所有以简单字符串形式提供名称的 payload 操作; - `TransformValueHandleTypeInterface` 类型的参数可绑定到所有以带 `^` 前缀的字符串提供名称的操作的结果扁平列表; - `TransformParamTypeInterface` 类型的参数可绑定到以 `#` 为前缀、分号分隔的整数常量列表。 - `entryPoint` 指定作为入口点的 transform 符号的名称。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-debug-payload-root-tag` | Select the operation with 'transform.target_tag' attribute having the given value as payload IR root. If empty select the pass anchor operation as the payload IR root. | 选择具有指定值的 `transform.target_tag` 属性的操作作为 payload IR 根;若为空则选择该 pass 的锚定操作作为 payload IR 根。 | | `-debug-bind-trailing-args` | Binds trailing arguments of the entry point to the payload operations with specified names. | 将入口点的尾部参数绑定到具有指定名称的 payload 操作。 | | `-disable-expensive-checks` | Disable expensive checks in the interpreter for a faster run. | 禁用解释器中开销较大的检查以加快运行速度。 | | `-entry-point` | Entry point of the pass pipeline. | Pass 流水线的入口点。 | ### -transform-preload-library **EN:** Preload transform dialect library **中文:** 预加载 transform 方言库。 **EN:** This pass preloads a transform library and makes it available to subsequent transform interpreter passes. The preloading occurs into the Transform dialect and thus provides very limited functionality that does not scale. **中文:** 该 pass 预加载一个 transform 库并使其对后续的 transform 解释器 pass 可用。预加载发生在 Transform 方言内部,因此提供的功能非常有限且不具备可扩展性。 **EN:** Warning: Only a single such pass should exist for a given MLIR context. This is a temporary solution until a resource-based solution is available. **中文:** 警告:对于给定的 MLIR 上下文,只应存在一个这样的 pass。这是一个临时解决方案,直到基于资源的方案可用为止。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-transform-library-paths` | Optional paths to files with modules that should be merged into the transform module to provide the definitions of external named sequences. | 可选的、包含应合并到 transform 模块中的模块文件的路径,以提供外部命名序列的定义。 | --- ## 'vector' Dialect Passes('vector' 方言 Pass) ### -lower-vector-mask **EN:** Lower ‘vector.mask’ operations **中文:** 降低(lower)`vector.mask` op。 ### -lower-vector-multi-reduction **EN:** Lower ‘vector.multi_reduction’ operations **中文:** 降低(lower)`vector.multi_reduction` op。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-lowering-strategy` | Select the strategy to control how multi_reduction is lowered. | 选择用于控制 `multi_reduction` 如何被降低的策略(strategy)。 | ### -lower-vector-to-from-elements-to-shuffle-tree **EN:** Lower vector.to_elements and vector.from_elements to a tree of vector.shuffle operations **中文:** 将 `vector.to_elements` 与 `vector.from_elements` op 降低为 `vector.shuffle` op 组成的树形结构。 --- ## TOSA Dialect Passes(TOSA 方言 Pass) ### -tosa-arith-const-to-tosa-const **EN:** Convert tensor arith.constant operations into tosa.const **中文:** 将张量 `arith.constant` 操作转换为 `tosa.const`。 **EN:** Normalizes tensor-valued arith.constant operations into tosa.const so that subsequent TOSA passes operate on a consistent representation of constants. **中文:** 将张量类型的 `arith.constant` 操作规范化为 `tosa.const`,使得后续 TOSA pass 在一致的常量表示上工作。 ### -tosa-attach-target **EN:** Attach tosa.target_env information to the given module. **中文:** 将 `tosa.target_env` 信息附加到给定模块(module)上。 **EN:** This pass allows the user to specify a TOSA target environment consisting of the following components: level, profiles and extensions. The target environment is attached to the module as an attribute, allowing other transformations to query the selected target and adapt their behaviour based on this information. **中文:** 该 pass 允许用户指定一个 TOSA 目标环境(target environment),由以下组件构成:level、profiles 和 extensions。目标环境以属性(attribute)形式附加到模块上,使其他变换可以查询所选目标并据此调整其行为。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-specification_version` | The specification version that TOSA operators should conform to. | TOSA 算子应符合的规范版本(specification version)。 | | `-level` | The TOSA level that operators should conform to. A TOSA level defines operator argument ranges that an implementation shall support. | 算子应符合的 TOSA 级别(level)。TOSA 级别定义了实现必须支持的算子参数范围。 | | `-profiles` | The TOSA profile(s) that operators should conform to. TOSA profiles enable efficient implementation on different classes of device. Each profile is an independent set of operations and data type combinations. | 算子应符合的 TOSA profile(档位)。TOSA profile 支持在不同类别设备上高效实现。每个 profile 是独立的算子和数据类型组合集合。 | | `-extensions` | The TOSA extension(s) that operators should conform to. TOSA profile extensions define optional operation and data type combinations. | 算子应符合的 TOSA extension(扩展)。TOSA profile 扩展定义了可选的算子和数据类型组合。 | ### -tosa-convert-integer-type-to-signless **EN:** Convert integer types to signless **中文:** 将整型类型转换为无符号标记(signless)类型 **EN:** This pass converts signed or unsigned integer types to signless. It currently does this greedily for all operators and can also change the signature of the function. Should the signature of the entrypoint function change, it will be the responsibility of the user to carry signedness information of the inputs and outputs independently. This can be a useful transformation for conversion to other formats that require strict adherence to the TOSA specification. **中文:** 该 pass 将有符号或无符号的整型类型转换为 signless(无符号标记)类型。当前实现对所有算子贪心地执行此转换,并可能同时修改函数签名。如果入口函数的签名发生变化,则用户有责任独立携带输入和输出的有/无符号信息。对于需要严格遵循 TOSA 规范的其他格式转换,这是一个有用的变换。 ### -tosa-downgrade-1-1-to-1-0 **EN:** Downgrade TOSA 1.1 specification constructs to TOSA 1.0 **中文:** 将 TOSA 1.1 规范结构降级到 TOSA 1.0 **EN:** Rewrites constructs which are only compatible in TOSA specification 1.1 and above to their TOSA 1.0 counterparts where possible. Downgrading is best-effort and validation should be performed afterwards to ensure compatibility with the TOSA 1.0 specification. **中文:** 尽可能将仅在 TOSA 规范 1.1 及以上版本中兼容的结构重写为其对应的 TOSA 1.0 形式。降级是尽力而为(best-effort)的,之后应执行校验以确保与 TOSA 1.0 规范的兼容性。 ### -tosa-experimental-input-shape **EN:** Override dynamic function arguments to specified static shapes. **中文:** 将动态函数参数覆盖为指定的静态形状(shape)。 **EN:** Pass that overrides the dynamic input shapes of function arguments to specified static shapes. If a specified static shape conflicts with the static dimensions in an original input shape, an error is reported. **中文:** 该 pass 将函数参数的动态输入形状覆盖为指定的静态形状。如果指定的静态形状与原输入形状中的静态维度冲突,则报告错误。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-args` | Comma-separated list of shape descriptions. Each description contains the argument name, a colon, and a shape with dimensions separated by x | 以逗号分隔的形状描述列表。每个描述包含参数名、一个冒号,以及由 `x` 分隔各维度的形状。 | ### -tosa-infer-shapes **EN:** Propagate shapes across TOSA operations **中文:** 在 TOSA 算子间传播形状(shape) **EN:** Pass that uses operand types and propagates shapes to TOSA operations. This includes legalizing rankless and dynamic shapes towards static. **中文:** 该 pass 使用操作数类型,将形状传播到 TOSA 算子上。这包括把无秩(rankless)和动态形状合法化为静态形状。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-fold-shape-expressions` | Fold TOSA shape operations when they have known input values | 当 TOSA shape 算子的输入值已知时进行折叠(fold)。 | | `-convert-function-boundaries` | If enabled, the pass will convert function I/O types as well. Otherwise casts will be inserted at the I/O boundaries. | 若启用,该 pass 将同时转换函数的 I/O 类型;否则会在 I/O 边界处插入 cast。 | ### -tosa-layerwise-constant-fold **EN:** Fold layerwise operations on constant tensors **中文:** 对常量张量上的层(layer)级算子进行折叠 **EN:** Pass that enables folding of full-layer operations on constant tensors. **中文:** 该 pass 启用对常量张量上完整层(full-layer)算子的折叠。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-aggressive-reduce-constant` | Always perform the reduce constant optimization. May add more tosa.const but would reduce runtime calculations | 始终执行 reduce 常量优化。可能会增加更多 `tosa.const`,但会减少运行时计算量。 | ### -tosa-make-broadcastable **EN:** TOSA rank Reshape to enable Broadcasting **中文:** 通过调整秩的 Reshape 来启用广播(Broadcasting) **EN:** Pass that enables broadcast by making all input arrays have the same number of dimensions. Insert RESHAPE operations to prepend dimensions of size one until the number of dimensions is equal. Implements approach similar to step 1 of Numpy 4-step broadcasting: https://numpy.org/doc/stable/reference/ufuncs.html#broadcasting **中文:** 该 pass 通过让所有输入数组具有相同的维度数来启用广播。插入 RESHAPE 算子在前方补上大小为 1 的维度,直到维度数相等为止。实现方式类似于 Numpy 4-step broadcasting 的第一步:https://numpy.org/doc/stable/reference/ufuncs.html#broadcasting ### -tosa-narrow-f64-to-f32 **EN:** Narrow F64 TOSA operations to F32 **中文:** 将 F64 的 TOSA 算子收窄为 F32 **EN:** This pass narrows TOSA operations with 64-bit floating-point tensor types to 32-bit floating-point tensor types. While TOSA itself has no double precision support, upstream conversions or frontends may still materialize F64 tensors temporarily, so this pass removes them before handing off to a TOSA backend. **中文:** 该 pass 将使用 64 位浮点张量类型的 TOSA 算子收窄为 32 位浮点张量类型。尽管 TOSA 本身不支持双精度,上游转换或前端仍可能临时生成 F64 张量,因此本 pass 在交给 TOSA 后端之前将其移除。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-aggressive-rewrite` | If enabled, all TOSA operations are rewritten, regardless or whether the narrowing is safe. This option may lead to data loss if not used carefully. | 若启用,所有 TOSA 算子都会被重写,无论收窄是否安全。若不谨慎使用,此选项可能导致数据丢失。 | | `-convert-function-boundaries` | If enabled, the pass will convert function I/O types as well. Otherwise casts will be inserted at the I/O boundaries. | 若启用,该 pass 将同时转换函数的 I/O 类型;否则会在 I/O 边界处插入 cast。 | ### -tosa-narrow-i64-to-i32 **EN:** Narrow I64 TOSA operations to I32 **中文:** 将 I64 的 TOSA 算子收窄为 I32 **EN:** This pass narrows TOSA operations with 64-bit integer tensor types to 32-bit integer tensor types. This can be useful for backends that do not support the EXT-INT64 extension of TOSA. **中文:** 该 pass 将使用 64 位整型张量类型的 TOSA 算子收窄为 32 位整型张量类型。对于不支持 TOSA 的 `EXT-INT64` 扩展的后端,此变换很有用。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-aggressive-rewrite` | If enabled, all TOSA operations are rewritten, regardless or whether the narrowing is safe. This option may lead to data loss if not used carefully. | 若启用,所有 TOSA 算子都会被重写,无论收窄是否安全。若不谨慎使用,此选项可能导致数据丢失。 | | `-convert-function-boundaries` | If enabled, the pass will convert function I/O types as well. Otherwise casts will be inserted at the I/O boundaries. | 若启用,该 pass 将同时转换函数的 I/O 类型;否则会在 I/O 边界处插入 cast。 | ### -tosa-optional-decompositions **EN:** Applies Tosa operations optional decompositions **中文:** 应用 TOSA 算子的可选分解(decomposition) **EN:** Pass to apply the Tosa operations decompositions exposed as populate functions in include/mlir/Dialect/Tosa/Transforms/Passes.h **中文:** 该 pass 用于应用作为 `populate` 函数暴露在 `include/mlir/Dialect/Tosa/Transforms/Passes.h` 中的 TOSA 算子分解。 ### -tosa-reduce-transposes **EN:** Reduce transposes through other operators **中文:** 通过其他算子化简 transpose(转置) **EN:** Pass that identifies and reduces tosa.TRANSPOSE operations through chains of operators. The pass traverses dependencies of tosa.TRANSPOSE operations until they terminate in either a tosa.RESHAPE that we can fold the hoisted tosa.TRANSPOSE into, a tosa.TRANSPOSE that forms the identity with the hoisted one, or a tosa.CONST with a dense elements attribute. It then propagates the hoisted transform upward through the intervening operators if the support is implemented. Finally, it observes that no duplication will occur of both the chain that was hoisted through and the new chain that results, and if so, it replaces the hoisted tosa.TRANSPOSE. The pass has an important use-case in cleaning up the results of frameworks that introduce a lot of data-layout transformations when legalizing to TOSA, a common one being transformations between NHWC and NCHW layouts. **中文:** 该 pass 识别并化简通过算子链的 `tosa.TRANSPOSE` 操作。pass 遍历 `tosa.TRANSPOSE` 操作的依赖,直到它们终止于:可折叠所提升(hoisted)`tosa.TRANSPOSE` 的 `tosa.RESHAPE`、与所提升 `tosa.TRANSPOSE` 构成恒等的另一个 `tosa.TRANSPOSE`,或带 dense elements 属性的 `tosa.CONST`。随后,若支持已实现,则通过中间的算子向上传播所提升的变换。最后,它观察被穿透的链和新产生的链都不会发生重复;若如此,则替换掉所提升的 `tosa.TRANSPOSE`。该 pass 的一个重要用例是清理那些在合法化到 TOSA 时引入大量数据布局(data-layout)变换的框架的结果,其中一种常见情形是在 NHWC 与 NCHW 布局之间的转换。 ### -tosa-validate **EN:** Validates TOSA dialect **中文:** 校验 TOSA 方言 **EN:** This pass validates if input TOSA operations match the specification for given criteria, e.g. TOSA profile. **中文:** 该 pass 校验输入 TOSA 算子是否符合给定条件(如 TOSA profile)的规范要求。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-strict-op-spec-alignment` | Verify if the properties of certain operations align the spec requirement | 校验某些算子的属性是否满足规范(spec)要求 | | `-allow-invalid-op-datatype-combinations` | Disable checks for operations that are determined to be invalid due to their operand/result datatypes not aligning with the 'Supported Data Types' sections of the specifciation | 关闭针对被判定为无效的算子的检查,即其操作数/结果的数据类型与规范(specifciation)中 "Supported Data Types" 章节不一致的算子。 | | `-validate-function-signature` | Verify if the function signature is valid for TOSA dialect, i.e. all function arguments and return types are tosa-conformant tensor types | 校验函数签名对 TOSA 方言是否有效,即所有函数参数和返回类型都是符合 TOSA 的张量类型。 | --- ## XeGPU Dialect Passes(XeGPU 方言 Pass) ### -xegpu-blocking **EN:** Block XeGPU ops into smaller size. This pass partitions operations that process large shapes into multiple operations on smaller shapes, as specified by the inst_data in the layout attribute. This enables each resulting operation to be efficiently mapped to a hardware instruction. **中文:** 将 XeGPU op 分块为更小的尺寸。该 Pass 将处理大型 shape(形状)的算子切分为对较小 shape 进行处理的多个算子,具体方式由 layout 属性中的 inst_data 指定。这使得每个生成的算子都能高效地映射到一条硬件指令。 ### -xegpu-optimize-peephole **EN:** Optimize XeGPU block load operations **中文:** 优化 XeGPU block load(块加载)操作 **EN:** This pass rewrites XeGPU loadNd operations into more optimal forms to improve performance. This includes, Rewriting transpose B loads into more optimal forms to use HW block transpose instructions for better performance. **中文:** 该 Pass 将 XeGPU loadNd 算子改写为更优的形式以提升性能。这包括:将转置(transpose)B 加载改写为更优的形式,以便使用硬件块转置指令获得更好的性能。 ### -xegpu-propagate-layout **EN:** Propagate and assign XeGPU layout information **中文:** 传播并分配 XeGPU layout(布局)信息 **EN:** This pass propagates the XeGPU layout information accross ops. Starting from a set of anchor operations (e.g. dpas, store_nd), this will propagate the layouts required for their operands to the producers. With this propagated layout information, pass will then update op result type with the layout information. **中文:** 该 Pass 在算子之间传播 XeGPU layout(布局)信息。从一组锚点(anchor)算子(例如 dpas、store_nd)出发,它会将这些算子的操作数所需的 layout 传播到其生产者(producer)。借助这些已传播的 layout 信息,Pass 随后会用该 layout 信息更新算子的结果类型。 **EN:** layout-kind option values: inst Propagate the inst_data field of the layout attribute. The default is chosen to maximize instruction-level granularity so that the user shape can be processed with the fewest instructions. For N-D operations, this granularity depends on W (width) and H (height) of the instruction shape. The B (block) dimension (or array length) is not included in the default configuration and must be enabled via a separate optimization pass. lane Propagate the lane_layout and lane_data fields of the layout attribute. Default values are selected to align with hardware. subgroup Propagate the sg_layout and sg_data fields of the layout attribute. Default values are selected to align with hardware. **中文:** layout-kind 选项的取值: inst 传播 layout 属性的 inst_data 字段。默认值被选为最大化指令级粒度(instruction-level granularity),从而用尽可能少的指令处理用户 shape。对于 N-D 算子,该粒度取决于指令形状的 W(宽度)和 H(高度)。B(block,块)维度(即数组长度)不包含在默认配置中,必须通过单独的优化 Pass 启用。 lane 传播 layout 属性的 lane_layout 和 lane_data 字段。默认值被选为与硬件对齐。 subgroup 传播 layout 属性的 sg_layout 和 sg_data 字段。默认值被选为与硬件对齐。 **Options / 选项:** | Option | EN description | 中文说明 | |---|---|---| | `-print-analysis-only` | Print the result of layout propagation analysis and exit. | 打印布局传播分析的结果并退出。 | | `-layout-kind` | Propagate `subgroup` / `inst` / `lane` level of xegpu layouts. | 传播 `subgroup` / `inst` / `lane` 级别的 xegpu layout。 | | `-index-bitwidth` | Vectors of `index` type should also be distributable, inst-data and lower levels need to know the index size. | `index` 类型的向量也应当可分布,inst-data 及更底层需要知道 index 的大小。 | ### -xegpu-sg-to-lane-distribute **EN:** Distribute XeGPU ops to lanes **中文:** 将 XeGPU op 分发到 lane(通道) **EN:** The pass distributes subgroup level XeGPU ops to lane level XeGPU ops. **中文:** 该 Pass 将 subgroup(子组)级别的 XeGPU op 分发为 lane 级别的 XeGPU op。 ### -xegpu-vector-linearize **EN:** Linearize n-D vectors to 1-D vectors **中文:** 将 n-D 向量线性化为 1-D 向量 **EN:** This pass linearizes n-D vectors to 1-D vectors for lowering to XeVM. **中文:** 该 Pass 将 n-D 向量线性化为 1-D 向量,以便降低(lowering)到 XeVM。 ### -xegpu-wg-to-sg-distribute **EN:** Transform WorkGroup level XeGPU code to SubGroup level **中文:** 将 WorkGroup(工作组)级别的 XeGPU 代码转换为 SubGroup(子组)级别 **EN:** This transform pass distributes the workgroup level computation to multiple subgroups based on the sg_layout and sg_data attributes. **中文:** 该变换 Pass 依据 sg_layout 和 sg_data 属性,将工作组(workgroup)级别的计算分发到多个 subgroup。 ---