first commit
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
# 阶段 6:Codegen(可执行体 lowering)✅
|
||||
|
||||
> 2026-08-15。对应规划阶段 6。源码:`src/iree/compiler/src/iree/compiler/Codegen/`。
|
||||
> **这是你之前接触过的部分,重点是建立「MLIR pass ↔ TVM schedule」的映射。**
|
||||
|
||||
## 1. Codegen 的职责
|
||||
|
||||
把 HAL 层交给它的 `flow.executable`(内含 linalg 计算)lowering 成设备代码(LLVM IR / SPIR-V)。
|
||||
由 HAL 的 TargetBackend 触发(见 [07-hal.md](07-hal.md) 第 3 节)。
|
||||
|
||||
按后端组织:
|
||||
- `LLVMCPU/` —— CPU(x86/ARM)
|
||||
- `LLVMGPU/` —— GPU(CUDA via NVVM、ROCm via ROCDL)
|
||||
- `SPIRV/` —— Vulkan
|
||||
- `VMVX/` —— 简单可移植参考后端
|
||||
- `WGSL/` —— WebGPU
|
||||
- `Common/` —— 跨后端共享逻辑
|
||||
|
||||
## 2. 关键 lowering 链(LLVMCPU,来自阶段 2 pass 序列)
|
||||
|
||||
```
|
||||
LLVMCPUSelectLoweringStrategy # 选 tiling/向量化策略(对应 TVM 选 schedule)
|
||||
→ TileAndDistributeToWorkgroups # workgroup 级 tiling
|
||||
→ LLVMCPUTileAndFuseProducerConsumer # tile-and-fuse(对应 TVM 的 compute_at + fuse)
|
||||
→ LLVMCPUTile # tiling
|
||||
→ LLVMCPUPeel # loop peeling
|
||||
→ LLVMCPUTileToVectorSize # tile 到向量大小
|
||||
→ GenericVectorization # 向量化(对应 TVM 的 vectorize)
|
||||
→ IREEComprehensiveBufferize # bufferize:tensor → memref(对应 TVM storage lowering)
|
||||
→ LLVMCPUVirtualVectorLowering # 向量 lowering
|
||||
→ ConvertToLLVM # 转 LLVM IR
|
||||
```
|
||||
|
||||
## 3. MLIR pass ↔ TVM schedule 对照(你的主场)
|
||||
|
||||
| TVM 0.6 schedule 原语 | IREE codegen 的 MLIR pass |
|
||||
|---|---|
|
||||
| `split`(循环拆分) | `LLVMCPUTile` + `LLVMCPUTileToVectorSize` |
|
||||
| `reorder`(循环重排) | tiling pass 里隐含 |
|
||||
| `fuse` + `compute_at` | `LLVMCPUTileAndFuseProducerConsumer` |
|
||||
| `vectorize` | `GenericVectorization` |
|
||||
| `unroll` | `LLVMCPUPeel` + 向量 lowering |
|
||||
| buffer 分配 / storage | `IREEComprehensiveBufferize`(tensor→memref) |
|
||||
| codegen(LLVM/CUDA) | `ConvertToLLVM` / `ConvertToNVVM` / `ConvertToROCDL` |
|
||||
|
||||
**核心差异**:TVM 的 schedule 是**用户手写/自动搜索**的显式变换序列;IREE 的 codegen 是
|
||||
**声明式 pass pipeline**,策略由 `LLVMCPUSelectLoweringStrategy` 基于 op 类型/shape 自动选择。
|
||||
(IREE 也有 `transform` dialect 支持手写 schedule,但那是在 linalg 之上。)
|
||||
|
||||
## 4. Dispatch ABI(运行时↔可执行体的接口,关键)
|
||||
|
||||
codegen 出来的 LLVM 函数(阶段 2 dump 见过)签名是:
|
||||
|
||||
```mlir
|
||||
llvm.func @matmul_dispatch_0_matmul_2x2x4_f32(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -> i32
|
||||
```
|
||||
|
||||
- 参数不是直接传 buffer,而是通过 `iree_hal_executable_dispatch_state_v0_t` 结构体(`DispatchABI.cpp` 定义)
|
||||
取 bindings —— 这是运行时和编译出的 kernel 之间的固定 ABI
|
||||
- 对应 TVM 里 kernel 的参数打包(`TVMArgs` / 显式参数)
|
||||
|
||||
## 5. 关键文件
|
||||
|
||||
| 文件 | 作用 |
|
||||
|---|---|
|
||||
| `LLVMCPU/LLVMCPUSelectLoweringStrategy.cpp` | 选策略(tiling 尺寸、向量化方案)——核心 |
|
||||
| `LLVMCPU/LLVMCPUTileAndFuseProducerConsumer.cpp` | tile-and-fuse |
|
||||
| `LLVMCPU/LLVMCPUTile.cpp` / `LLVMCPUPeel.cpp` | tiling / peeling |
|
||||
| `LLVMCPU/LLVMCPUTileToVectorSize.cpp` | tile 到向量 |
|
||||
| `LLVMCPU/LLVMCPUVirtualVectorLowering.cpp` | 向量 lowering |
|
||||
| `LLVMCPU/DispatchABI.cpp` | dispatch ABI |
|
||||
| `LLVMCPU/ConvertToLLVM.cpp` / `LLVMCPULowerExecutableTarget.cpp` | 转 LLVM |
|
||||
| `LLVMGPU/ConvertToNVVM.cpp` / `ConvertToROCDL.cpp` | GPU 后端 |
|
||||
| `LLVMGPU/KernelConfig.cpp` | GPU kernel 配置 |
|
||||
|
||||
## 6. 源码阅读路径
|
||||
|
||||
```
|
||||
src/iree/compiler/src/iree/compiler/Codegen/
|
||||
├── Common/ # 跨后端共享
|
||||
├── Interfaces/ # 接口
|
||||
├── LLVMCPU/ # CPU 后端
|
||||
│ ├── LLVMCPUSelectLoweringStrategy.cpp # 先读这个(策略选择)
|
||||
│ ├── LLVMCPUTileAndFuseProducerConsumer.cpp
|
||||
│ └── DispatchABI.cpp
|
||||
├── LLVMGPU/ # GPU 后端(NVVM/ROCDL)
|
||||
├── SPIRV/ # Vulkan
|
||||
└── Transforms/ # 通用变换
|
||||
```
|
||||
|
||||
> 学习建议:你有 codegen 经验,重点看 `LLVMCPUSelectLoweringStrategy.cpp` 理解「策略怎么选」,
|
||||
> 以及 `DispatchABI.cpp` 理解「kernel 和运行时怎么对接」。GPU 后端看 `LLVMGPU/KernelConfig.cpp`。
|
||||
Reference in New Issue
Block a user