first commit

This commit is contained in:
ylhan
2026-08-20 17:20:09 +08:00
commit 8049b6f58d
14 changed files with 1649 additions and 0 deletions
+92
View File
@@ -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`。