LlvmTpu 内在函数目录
本页中的每个地址、符号、偏移和字符串都逐字节精确读取自
libtpu-0.0.40-cp314wheel 中的libtpu.so(构建libtpu_lts_20260413_b_RC00,BuildID md589edbbe81c5b328a958fe628a9f2207d,781,691,048 字节,未剥离符号,.text/.rodataVMA == 文件偏移)。其他版本会不同;应把每个 VA 都视为绑定到该版本。
摘要
TPU 后端有两个不同的 op 表面。TensorCore 路径是含 86 个 op 的 tpu 目标方言,它降低到 322 个 mlir::llo::*Op 类,再下降到 LLO bundle(tpu → LLO ODS 降低 覆盖了这一下降过程)。本页记录的是另一个表面:LlvmTpuDialect,一个独立的 MLIR 方言,包含 1356 个 tpu_* 内在 op,它是 SparseCore(嵌入处理协处理器)的栈底指令表面。每个 op 注册为 mlir::sparse_core::tpu_X_Y_Z,并打印为 LLVM 内在函数名 llvm.tpu.X.Y.Z(下划线→点)。这些 op 不会降低到 LLO;它们通过 Lower to SparseCore LLVM 下降为真正的 LLVM-IR 内在函数调用,并到达 SparseCore LLVM 后端,在那里由 addrspacecast ISel 和各引擎的 ISel 匹配它们。
熟悉 LLVM 的读者应记住一个类比:这是一个以 MLIR 方言形式物化的 TableGen IntrinsicsTPU.td 表面。每个 llvm.tpu.* 名称都是一个 LLVM 内在函数;每个名称同时也是一个已注册的 MLIR op,携带标准的 23 槽 RegisteredOperationName::Model<Op> ABI。这两个视图是同一集合,并通过两种独立方式恢复出来(1356 个 Model<tpu_*> vtable,以及 1356 个 llvm.tpu.* 打印名字符串;在下划线→点映射下集合完全相同)。最主要的结构事实是:硬件变体由 op 身份编码,而不是由属性编码:1356 个 op 中有 834 个(62 %)属于 tpu_stream_* 嵌入 gather/scatter 家族,这是一个 {pattern × verb × dtype × memspace} 叉积,其中每个单元格都是独立注册的 op。stream op 没有 dtype 属性;dtype 在其名称中。
本页负责家族分类、各家族代表性签名,以及 ID 表组织(10 批次注册器)。它不会重新推导逐 cast 的地址空间 ISel(那是 addrspacecast ISel 的内容)、tpu 方言 ODS(那是 tpu → LLO ODS 降低 的内容),或 SparseCore 后端引擎编码(那些见 SparseCore ISA 槽位页面)。对于重新实现,契约是:
- Model↔打印名对应关系 — 机械的
tpu_X_Y↔llvm.tpu.X.Y映射,以及为什么它是零不匹配的 1:1 对应。 - 20 类功能分类 — 按前缀对 1356 个中的 1348 个进行名称家族分组(每类大小均已逐字节确认;见 20 个类别);每类映射到其 SparseCore 引擎或 LLO/EmitX 目标。
- ID 表组织 — 10 批次
registerLlvmTpuDialectOperations0..9注册器、为何拆分,以及它与 115-op ScDialect 路径的区别。 - ODS 形状恢复规则 — 带类型的
tpu_*::create参数列表就是操作数/结果声明,并有已验证的逐家族元数。
| 方言类 | mlir::sparse_core::LlvmTpuDialect(ctor LlvmTpuDialectC1EPNS_11MLIRContextE) |
| 内在函数数量 | 1356(Model<tpu_*> vtables == llvm.tpu.* 字符串,集合完全相同) |
| 注册器 | registerLlvmTpuDialectOperations @ 0x146d0560 → 尾调用 …Operations0..9 |
| 打印名规则 | C++ tpu_X_Y_Z ↔ intrinsic llvm.tpu.X.Y.Z(_→.);comm -23 == 0 |
| 地址空间 | LlvmTpuDialect::AddressSpaceDescription(int) @ 0x135462c0(base 0xc9=201,span 0x18) |
| 消费 pass | LowerToSparseCoreLlvmPass::runOnOperation @ 0x13566d00;lowerFunc @ 0x13568280 |
| 主导类别 | tpu_stream_* — 834 / 1356(SparseCore 嵌入 gather/scatter 引擎) |
| 带类型 create 覆盖率 | 466 / 1356 携带带类型的 create(从符号读出 ODS 形状);890 个默认 builder |
| 置信度 | CONFIRMED(字节锚定)用于枚举/分类/注册;逐类 HW 目标按标注 |
双表面模型
目的
在目录之前,读者必须先理解为什么还存在第二个 TPU op 方言,以及为什么负责 tpu 方言→LLO 下降的页面不负责这一部分。这种拆分是结构性的,而非偶然:TensorCore 和 SparseCore 是两种不同机器,拥有不同 ISA,编译器也把它们建模为不同的 MLIR 方言。
拆分
tpu 方言(86 个 op)是 TensorCore 目标:matmul/MXU、VPU 向量 op、sequencer,经由 322 个 llo.*Op 类下降(tpu → LLO ODS 降低)并打包进 VLIW bundle。LlvmTpuDialect(1356 个 op,本页)是 SparseCore 目标:一个嵌入表流处理器,其原语包括间接 gather/scatter、sflag 原子、循环缓冲寄存器(CBREG),以及 SparseCore 内存池之间的地址空间 cast。SparseCore op 不会被打包进 LLO bundle,而是变成 LLVM-IR 内在函数调用,并由 SparseCore LLVM 后端生成代码。
注意 — 这 1356 个内在函数不会通过 115-op ScDialect 的
addOperations路径(0x14594f60)注册;只扫描该路径的方言清单会认为LlvmTpuDialect是空的。内在函数通过独立的 10 批次registerLlvmTpuDialectOperations路径注册,该路径记录在 ID 表组织 中,也是它们的RegisteredOperationName::Model<Op>vtable 被物化和验证的位置。
Model↔打印名对应关系
每个内在函数在二进制中存在两次,而且两种形式可以机械地互相转换:
// (a) the registered MLIR op — a RegisteredOperationName::Model<Op> vtable:
// _ZTVN4mlir23RegisteredOperationName5ModelINS_11sparse_core11tpu_syncaddEEE
// 1356 such vtables for mlir::sparse_core::tpu_* classes.
// (b) the printed LLVM-intrinsic name string, in .rodata:
// "llvm.tpu.syncadd"
// 1356 such strings.
//
// The map is purely lexical:
// class tpu_X_Y_Z -> intrinsic llvm.tpu.X.Y.Z // s/^tpu_/llvm.tpu./ ; s/_/./g
// Applying it to the class list and diffing against the string list:
// comm -23 (mapped-classes) (string-list) == 0 // zero mismatch, both ways因此,每个已注册 op 恰好有一个打印出的 llvm.tpu.* 名称,反之亦然。这是规范的、源自 IntrinsicsTPU.td 的表面:C++ 类是 ODS 注册的 MLIR op;llvm.tpu.* 字符串是它带入后端的 LLVM 内在函数名。
陷阱 — 点/下划线边界只是前缀和字段分隔符,不是分词器。
tpu_dma_hbm_to_tilespmem_sc_simple↔llvm.tpu.dma.hbm.to.tilespmem.sc.simple— 每个_都会变成.,包括hbm_to_tilespmem内部的那些。重新实现者若对_to_做特殊处理,会使两个命名空间失去同步。
功能类别分类
目的
1356 个内在函数按名称家族前缀分成 20 个功能类别。大型清晰前缀类别(stream 834、pack/unpack 87、vld/vst 74、wait 47、dma 40、scan 32、vcvt 28、sync 25、alloca 24、rdreg/setreg 21、addrspacecast 16、sort 10、i1 5)已通过对打印名字符串集合执行 rg -c 逐字节确认;较小的边界类别(transcendental/EUP、scalar-ALU、ptr/addressing、shuffle、trace、CBREG、task)是名称家族估计,其精确成员无法用 grep 干净地隔离。这 20 个大小不是精确分区,它们覆盖 1356 个中的 1348 个(关于缺失的八个 op,见 20 个类别)。这是本页的核心重新实现工件:它告诉读者每个具名内在函数驱动哪个 SparseCore 硬件单元,而不必倾倒 1356 行。该分类通过名称家族分组恢复,并与打印名字符串集合交叉核对;逐类别硬件目标则连接到 SparseCore 引擎页面和 V5+ EmitX 位位置工作。
20 个类别 {#the-20-classes}
#ops = 类别大小;HW target = 它降低到的 SparseCore 引擎 / LLO 槽位;st = C(编码已在相邻页面字节确认)或 I(引擎已确认,逐叶 opcode 为推断)。
| #ops | 功能类别(tpu_* 前缀) | HW 目标 / 降低 | st |
|---|---|---|---|
| 834 | sparsecore-stream(stream_*) | SparseCore stream/scatter 引擎描述符(linear/strided/indirect × gather/scatter/vreg,CBREG-windowed);→ 通过 LowerToSparseCoreLlvm 变成 LLVM 调用 | I |
| 87 | pack / unpack(pack*, unpack*) | VPU pack/unpack 槽位 → llo.vpack*/llo.vunpack*;用于 MXU/quant 的子字节暂存(b32→b16→b8→b4→b2→b1,e4m3/e5m2/s8/u8) | C |
| 74 | vector load/store(vld*, vst*) | VPU mem 槽位 → llo.vector_{load,store}[_masked];_idx 索引式,_cb CBREG-windowed,_strided,_add scatter,_np no-predicate | C |
| 47 | semaphore wait/watch(wait*, watch*) | sflag VWait 槽位 → llo.vwait.{eq,ne,lt,le,gt,ge}[.done];_yieldable=seq-yield,_imem=instr-mem,ordone=or-done | C |
| 40 | DMA descriptor(dma_*_sc_*) | SparseCore DMA 引擎命令(simple/single_strided/general 层级);8/10/16 操作数描述符;参见 ScDialect DmaSimpleStart | C |
| 32 | scan / segment-scan / reduce({add,min,max}_*scan*) | SparseCore scan 单元(add/max/min × full/half/1xN/2xN × seg × index)— 嵌入聚合原语 | I |
| 28 | vector convert(vcvt*, cvt*) | VPU convert 槽位 → llo.vcvt.*;f32↔bf16/bf8/hf16/if8/s4/s8/u4/u8;_sr=stochastic-round,_pr=probabilistic | C |
| 25 | semaphore set/add(syncadd*, syncset*, sfence, sync{donemov,pamov,readpa,setpa}) | sflag VSync 槽位 → llo.vsync.{add,set}[.done,.remote];_remote=ICI peer,_tile/_pa=tile/public bank,_doneinv=invert done | C |
| 24 | transcendental / EUP(rcp,rsqrt,tanh,sin,cos,erf,log2,pow2,sigshft) | EUP VALU3 push(Alu3 op0 + 5-bit selector)+ PopEupResult;每个 bare + _macro push+pop 对 | C |
| 24 | alloca / allocate(alloca*, allocate*) | SparseCore allocator(smem/spmem/vmem/sflag/hbm/iova/timem/tilesmem/tilespmem/dreg/cbreg + _dyn + _any);参见 ScDialect Alloca | C |
| 21 | control register rd/set(rdreg_*, setreg_*) | scalar RdReg/SetReg → SCS scalar 槽位;cycle counters、tid/scid/tag id regs、fsr/ddr/dmacrdt/sflagrange | C |
| 19 | pointer / addressing / loop-bc(inttoptr,ptrtoint,bc_*,…) | LLVM inttoptr/ptrtoint/addrspace + loop bytecode(bc_loop_*, bc_load/store_aliaddr, bc_select_predicate, make_restrict_ptr) | C |
| 16 | addrspacecast(addrspacecast*) | LLVM addrspacecast → SparseCore 地址空间 ID(base 201;AddressSpaceDescription @ 0x135462c0) | C |
| 14 | scalar ALU / scalar mem(shll,shra,sadd_ov,addcarry,…) | SCS scalar 槽位:shll/shra/shrl/sshllo shifts、sadd_ov/ssub_ov/sshla_ov overflow-add、addcarry、add_{high,low}_f32 | C |
| 14 | lane / sublane shuffle / permute(vrot_sublane,vperm,sc_permute) | VPU cross-lane 槽位 → llo.vrot.slane/llo.vperm.sublane/llo.vslaneseq/vshift_insert/sc_mask_permute | C |
| 12 | CBREG / circular-buffer(rdcbreg,wrcbreg,cbreg_add,…) | scalar CBREG ops:rd/wr/add/copy CBREG {base,offset,size};16 CBREGs/bank,dual smem/tilespmem base,allocate_cbreg | C |
| 12 | trace / telemetry / sc-control(sc_*,strace,event,read_*cycle) | SparseCore control/trace:strace/event/spill_debug/log/mprefix,read_{global,local}_cycle_count,ssetpstate/ssettm | C |
| 10 | sort / unique / dupcount(sort*,uniquef,dupcntf,vmpcnt) | SparseCore sort/unique 单元:sort_{asc,dsc}d{f,i},uniquef/i,dupcntf/i,vmctz/vmpcnt_ones(embedding dedup) | I |
| 10 | task / control / structural(task_*,loop_*,barrier,nop,…) | SparseCore tile-task + structural:task_dispatch、loop_{name,parallel}、barrier、nop、delay、clear_ibuf、halt_trap、tileid | C |
| 5 | i1-mask width conversion(*i1_to_*i1) | VPU mask 槽位:tpu_{8,16,32}i1_to_{8,16,32}i1 — vector-mask 宽度重打包 | C |
834+87+74+47+40+32+28+25+24+24+21+19+16+14+14+12+12+10+10+5 = 1348 (of 1356)注意 — 类别大小已逐个字节确认(对
llvm.tpu.*字符串集合执行rg -c),但这 20 行是名称家族分组,不是精确分区:它们合计为 1348,比 1356 总数少八个。缺口位于软边界类别(transcendental/EUP、scalar-ALU、ptr/addressing、trace、task),其中少数 op,例如exponent、*_macro对,以及杂项 control/structural 内在函数,不落入任何单一前缀行。应把该分类视为按前缀覆盖 1356 个中的 1348 个,而不是已验证的 1:1 分区。sync 类别拆分为:9 个syncadd*+ 12 个syncset*+sfence+ 4 个 singleton = 25。特性 — 五个最大类别(stream、pack/unpack、vld/vst、wait、dma)为 834+87+74+47+40 = 1082,占 1356 的 80 % — 该表面 80 % 是 SparseCore 数据移动,不是计算。transcendental/EUP 类有 24 个 op,scalar-ALU 类有 14 个;SparseCore 是一台 gather/scatter/sflag 机器,自身只做很少算术。重新实现者在分配工作量时应预期 stream-engine 描述符会主导工作,而不是数学运算。
Stream 家族(834 个 op)
目的
tpu_stream_* 家族占内在函数表面的 62 %,也是最重要的 SparseCore 原语:嵌入表 gather/scatter 引擎。它的 834 路爆炸并不是 834 个互不相关的 op,而是一个四轴叉积,其中每个单元格都是不同的已注册内在函数,因此逐 (pattern,verb,dtype,memspace) 的 stream-engine 命令由 IR 层面的 op 身份选择,而不是由运行时解码的属性选择。
叉积轴
llvm.tpu.stream.<pattern>.[vreg.]{gather|scatter}.[cb.][add.]<dtype>.<src>.to.<dst>
axis values how it splits the 834
--------------------------------------------------------------------------------------
pattern linear (180) · strided (114) · indirect (540) address-generation mode
verb vreg (360) · gather (246) · scatter (228) direction / lane-spread
dtype bf16 · e4m3 · e5m2 · f32 · s16 · s32 (6) exactly 111 ops each (6×111=666 dtyped)
transfer _to_tilespmem 399 · _to_spmem 210 · _to_smem 27 src→dst memspace pair
· _to_hbm4b 15 · _to_hbm 15
modifier _cb_ (CBREG-windowed, 556) · _add (scatter-add) · _np (no-predicate)indirect pattern 占主导(540),因为它就是嵌入查找模式:索引流选择行。_cb_(CBREG-windowed)修饰符出现在 834 个中的 556 个上;这些窗口化形式使用 INDIRECT_OFFSET_SOURCE_CBREG 源进行嵌入表窗口化(见 CBREG)。gather 将行拉入 tile-local SPMEM(因此 _to_tilespmem 是最大的传输桶);scatter/scatter-add 将累积梯度推回外部。
其编码的流水线
HBM embedding table tile-local SPMEM
┌───────────────┐ indirect gather ┌──────────────┐
│ row 0 │ ── (CBREG-windowed) ─────▶ │ gathered rows│
│ row 1 │ indexed by offset │ │
│ … │ stream └──────┬───────┘
└───────────────┘ │ compute (forward)
▲ ▼
│ scatter-add (_add) ┌──────────────┐
└──────── accumulate gradients ────── │ updated rows │
└──────────────┘代表性签名
// tpu_stream_linear_gather_add_f32_hbm_to_tilespmem
// ::create(OpBuilder&, Location, Value, Value, Value, Value, Value, Value) // 6 operands
// tpu_stream_indirect_gather_add_bf16_hbm_to_tilespmem
// ::create(OpBuilder&, Location, Value ×8) // 8 operands
//
// The operand count tracks the pattern: linear/strided forms carry 6 SSA operands
// (src/dst handle + base/offset/size + sflag); the indirect forms carry 8
// (the extra two are the index/offset-stream + its CBREG window).注意 — 所有 834 个逐叶内在函数→数字 stream-engine 命令只在类别→引擎层面推断。类别映射到 SparseCore stream 引擎,描述符操作数形状已逐字节恢复;逐
(pattern,verb,dtype,memspace)的 HW 命令值属于 SparseCore stream ISA,是 DMA 描述符的同级内容,并未对 834 个逐一字节倾倒。见 Stream Gather/Scatter。
ODS 形状恢复
目的
每个内在函数的操作数/结果声明可以在没有 TableGen 源码的情况下从二进制中恢复,方法与 tpu → LLO ODS 降低 恢复 LLO 签名的方式相同:带类型的 create 符号经反混淆后的参数列表就是源码顺序中的 ODS 声明。
恢复规则
// create(OpBuilder&, Location, <ODS args in declaration order>)
// mlir::Type -> 1 explicit result type (inference-free op)
// mlir::Value -> 1 SSA operand
// Cross-checked against the op's NOperands<N> trait, which pins the operand count
// independently of the create arg list (e.g. tpu_syncadd carries NOperands<2>).1356 个中有 466 个携带带类型的 create;其余 890 个使用通用的 (TypeRange, ValueRange, ArrayRef<NamedAttribute>) 默认 builder(结果类型通过 SameOperandsAndResultType/InferType 推断,操作数数量按名称家族元数确定)。已针对二进制验证的带类型形式:
| intrinsic(class) | create args(Location 之后) | operands |
|---|---|---|
tpu_addrspacecast(addrspacecast) | Type, Value | 1 res, 1 opnd |
tpu_addrspacecast_smem / _spmem / _*_tec | Type, Value, Value | + tile-window/base |
tpu_dma_*_sc_simple(DMA) | Value ×8 | 8-field descriptor |
tpu_dma_*_sc_single_strided(DMA) | Value ×10 | + stride |
tpu_dma_*_sc_general(DMA) | Value ×16 | multi-dim |
tpu_stream_linear_*(stream) | Value ×6 | stream descriptor |
tpu_stream_indirect_*(stream) | Value ×8 | + index/offset stream |
tpu_syncadd(sync) | Value, Value | sflag, delta |
tpu_fetch_and_add(sync) | Value, Value, Value | sflag, addr, value |
tpu_*_macro(EUP,例如 tpu_sin_macro) | Type, Value | 1 res, 1 opnd |
tpu_rdcbreg_offset / _size(CBREG) | Type, Value | result, cbreg |
tpu_wrcbreg_offset(CBREG) | Type, Value, Value | cbreg, value |
tpu_inttoptr / tpu_ptrtoint(ptr) | Type, Value | result, val |
DMA _single_strided 层级携带 10 个 SSA 操作数:经反混淆的 tpu_dma_hbm_to_hbm_sc_single_strided::create 参数列表是 Value + 9×S5_(对先前 Value 类型的反向引用),使 stride 层级比 _simple 8 多两个操作数,并低于 _general 16。stream 家族同样不统一:linear/strided pattern 携带 6 个操作数,而 indirect pattern 携带 8 个,额外两个是 index/offset stream 及其 CBREG window。
ID 表组织 {#id-table-organisation}
目的
重新实现者必须复现 1356 个 op 如何注册进一个方言。答案是 10 批次注册器 — 一种 TableGen 模式,将一个逻辑上的 addOperations<…> 拆成十个函数,以限制每个函数的实例化大小。这就是本页的“ID 表”结构:内在函数 ID 按十个批次的注册顺序分配。
注册器
LlvmTpuDialect::initialize
└─ registerLlvmTpuDialectOperations @0x146d0560 ── tail-calls 10 sub-registrars:
├─ registerLlvmTpuDialectOperations0 @0x146d05c0
├─ registerLlvmTpuDialectOperations1 @0x1472bea0
├─ registerLlvmTpuDialectOperations2 @0x1478b500
├─ registerLlvmTpuDialectOperations3 @0x147e1c40
├─ registerLlvmTpuDialectOperations4 @0x14835b80
├─ registerLlvmTpuDialectOperations5 @0x148891c0
├─ registerLlvmTpuDialectOperations6 @0x148dc3c0
├─ registerLlvmTpuDialectOperations7 @0x1492d5c0
├─ registerLlvmTpuDialectOperations8 @0x14982d00
└─ registerLlvmTpuDialectOperations9 @0x149d88e0 (last batch)
── 10 × ~135 ops = 1356每个批次都是一个可变参数 addOperations<tpu_X, tpu_Y, …>,为每个模板参数物化一个 RegisteredOperationName::Model<Op>,也就是标准 MLIR op 注册 ABI,只是拆分成了十个函数。该方言中没有单独的数字“intrinsic ID enum”表:op 的身份就是它的 TypeID/RegisteredOperationName,而打印出的 llvm.tpu.* 名称就是 LLVM translator 发出的 ID。Model vtable 跨越一个连续的 .data.rel.ro 区域(tpu_16i1_to_32i1 … tpu_wrcbreg_tilespmem_base)。
特性 — ≤256-op 的批次拆分是 TableGen 产物,不是语义分组。批次 N 不对应功能类别 N;同一家族的 op(例如 834 个 stream)按字母类别顺序散布在所有十个批次中。重新实现者不应假设批次成员关系除了“在这里注册这些约 135 个 op”之外还携带任何含义。
注册绑定
function registerLlvmTpuDialectOperations(LlvmTpuDialect *d): // 0x146d0560
registerLlvmTpuDialectOperations0(d); // each batch:
… // addOperations<tpu_A, tpu_B, …>(d)
return registerLlvmTpuDialectOperations9(d); // -> RegisteredOperationName::insert ×135方言类是 mlir::sparse_core::LlvmTpuDialect(ctor LlvmTpuDialectC1EPNS_11MLIRContextE)。它的配套 helper — AddressSpaceDescription(int) @ 0x135462c0、GetAnyTypeFromAddressSpace(int)、attr parse/print 对,以及 target-CPU 属性谓词 — 是这些内在函数依赖的方言级机制,用于内存空间和目标解析。
桥接到 LLVM 后端
目的
这些内在函数不会停在 MLIR。LowerToSparseCoreLlvmPass 将每个 tpu_* op 重写为其 LLVM 方言形式,使 SparseCore LLVM 后端可以为它生成代码。本节命名该桥接,并指向负责每条降低分支的页面。
消费 pass
xla::tpu::sparse_core::CreateLowerToSparseCoreLlvmPass @0x135667c0 ── factory
└─ LowerToSparseCoreLlvmPass::runOnOperation @0x13566d00 ── driver
└─ lowerFunc @0x13568280 ── per-op rewrite按类别,降低分支各不相同:
| class | lowers to | owned by |
|---|---|---|
| addrspacecast | 按 intrinsic ID 选择的 LLVM addrspacecast / INTRINSIC_WO_CHAIN | addrspacecast ISel |
| transcendental / EUP | EUP VALU3 push(Alu3 op0 + 5-bit selector)+ PopEupResult | EUP 超越函数槽位 |
| CBREG | scalar CBREG ops(ReadCbreg 0x36 / WriteCbreg 0x35 / AddCbreg 0x33) | CBREG |
| sparsecore-stream | 逐 (pattern,verb,dtype,memspace) 的 stream-engine 描述符 | Stream Gather/Scatter |
| sync / wait | sflag VSync/VWait LLO ops | VPU 槽位 |
| pack/unpack, vcvt, vld/vst, permute | VPU 槽位 op(llo.v*) | VPU 槽位 |
| scan / sort / unique | SparseCore scan/sort/dedup 单元 | Scan 数据路径, Rank & Permute / Radixsort |
注意 — addrspacecast 分支不是
ISD::ADDRSPACECAST(0xf4)降低。SC cast 内在函数作为内在函数调用(INTRINSIC_WO_CHAIN)存活到 LLVM-IR 中,不同于 TensorCore 前端真正的addrspacecast指令。关于完整的逐 cast from→to 映射,以及为什么把 SC cast 接入LowerADDRSPACECAST会产生一个因CannotYetSelect而陷入的后端,见 addrspacecast ISel。
未恢复内容
给重新实现者的真实缺口:
- 逐叶 stream-engine 命令(834 个 op)。 类别→引擎已确认,描述符操作数形状已恢复;逐
(pattern,verb,dtype,memspace)的数字 HW 命令值没有单独逐字节倾倒。这是 SparseCore stream ISA,是 DMA 描述符的同级内容。 - 逐内在函数 LLVM
IntrProperties位集。 每个 op 携带哪些OpInterface可从 interface-Model 符号观察到(AliasAnalysis 546、MemoryEffect 285、Bytecode 188、AccessGroup 180);驱动后端调度/别名分析的精确逐 opIntrNoMem/IntrArgMemOnly/IntrWillReturn位集未转录。 - 890 个默认 builder op 的精确元数 + 结果
TypeConstraint。 已按名称家族和存在时的NOperands<N>trait 恢复;逐 opverifyInvariantsImpl字节解码(1-vs-2 操作数,Vreg/Mask/Scalar/Ptr 结果谓词)未穷尽遍历。 - 完整的数字地址空间 ID 表。
AddressSpaceDescriptionswitch base(201)和抽样 case 字符串(HBMAny,SflagAny,SflagTile,TileSmem,以及 Smem/Sflag/HBM/Dreg)已解码;完整 ID↔space 映射和 16 个 addrspacecast from→to ID 对在 addrspacecast ISel 中补全。 - scan/sort/unique 引擎 opcode 编码(32+11 个 op)。 已按名称映射到 SparseCore scan/sort/dedup 单元;逐 op HW 命令位布局未解码(这些是 SparseCore 专用计算单元,不是 TensorCore LLO 槽位)。
交叉引用 {#cross-references}
- tpu → LLO ODS 降低 — 另一个表面:86-op
tpu方言降低到 322 个llo.*Op类;本页复用的从create恢复 ODS 的规则 - TPU 编译器 — Part V 定位;SparseCore 降低位于五阶段下降中的位置
- 降低到 SparseCore LLVM — 将这些内在函数转成 LLVM-IR 的消费
LowerToSparseCoreLlvmPass - Dot/Conv MXU 降低 — TensorCore matmul 降低,与 SparseCore stream 引擎形成对比
- addrspacecast ISel — 指令选择处的 16 个 addrspacecast 内在函数;完整 from→to 地址空间映射
- Stream Gather/Scatter — 834-op stream 家族的引擎侧细节
- CBREG — CBREG 和
_cb_stream 内在函数驱动的每 bank 16 个 CBREG 的循环缓冲区 - Scan 数据路径 — 32 个 scan 内在函数瞄准的 scan/segment-scan 引擎
- Rank & Permute / Radixsort — 11 个 sort 内在函数瞄准的 sort/unique/dedup 单元
- EUP 超越函数槽位 — 24 个 transcendental 内在函数降低到的 EUP VALU3 push/pop
- VPU 槽位 — pack/unpack、convert、load/store、permute 和 sync/wait 内在函数瞄准的 VPU 槽位 op
- MXU 槽位 — pack/unpack 暂存馈入的 MXU bundle 槽位