Skip to content

Fat Pointers (AS7/8/9)

本页中的每个地址、偏移和值都逐字节精确地读取自 libtpu-0.0.40-cp314 wheel 中的 libtpu.so(构建 libtpu_lts_20260413_b_RC00,BuildID md5 89edbbe81c5b328a958fe628a9f2207d)。其他版本会不同。

摘要

本页记录 SparseCore (SC) 指针表示,以及 libtpu.so 中并存的两套指针编号方案:TPU DataLayout 中声明的 AS7/AS8/AS9 “胖指针”保留区,以及后端实际使用的 SparseCore 地址空间 ID 表。首要结论是一个负面结论,并且对重新实现至关重要:160/128/192 位的 AS7/8/9 胖指针是继承来的 AMDGPU 样板,没有任何 TPU 或 SparseCore op 会构造它们。 它们原样出现在 TPU data-layout 字符串中,是因为 TPU TargetMachine 共享 LLVM 的 AMDGPU buffer-fat-pointer ABI 片段,而且二进制里甚至带着 AMDGPU 针对它们的诊断信息;但在整个 SC MLIR-lowering、SC IR-emitter 和 jellyfish LLO-emitter 中,传给 LLVMPointerType::get / PointerType::get 的地址空间只有 0x00 以及 0xC9..0xE1 / 0x1F5 / 0x1F6 这个 SparseCore 区间。这两个编号空间完全不相交。

需要丢弃的心智模型,是来自 AMDGPU 的读者会自然带来的那一个:SparseCore 地址是一个 160 位结构,把 {descriptor, core/chip, offset} 打包进 AS7 胖指针的位中。事实并非如此。SparseCore 指针至多是一个 64 位 LLVM 指针,其寄存器内值携带 32 位 word offset0xCA/0xC9/0xCB/0xCC 地址空间不在 DataLayoutp 列表中,所以它们采用默认的 p:64:64 表示,而在它们之间重新打标签的 addrspacecast 会降低为类型为 MVT::i32 的保值 SDNode。AS7 保留区看起来应当携带的路由信息,也就是哪个 core/chip、哪个 tile,实际上作为独立 SSA 操作数传递:跨芯片 remote cast 使用 destination-id 操作数,on-tile TEC cast 使用 tpu_tileid 操作数。

本页分三部分。第一,AS7/8/9 胖指针保留区,包括三种格式是什么、AMDGPU ABI 为它们定义的逐字段位布局,以及 TPU 构建只是死继承这些内容的字节证据。第二,SparseCore 地址空间 ID 表,包括跨三个数值区间的 20 个带描述 ID、每个 ID 的后备内存池和 on-tile/off-tile 语义,它们从三个互逆的 switch/table 函数恢复而来。第三,实际的 SparseCore 指针表示,包括 64 位/32 位 word-offset 模型、为什么 tile 和 core 路由是操作数而不是指针位,以及一个指针的地址空间整数如何流经 lowering。MLIR MemorySpaceCastllvm.addrspacecast 的转换见 addrspacecast ISel;on-tile 的 2 操作数 tile-id cast lowering 见 Tile-ID Cast;本页负责的是表示和 AS-id 表

对重新实现而言,契约是:

  • 不要实现 AS7/8/9 构造器。 没有 SparseCore op 会物化 160/128/192 位指针。该保留区在此构建中是死的;如果重新实现从 DataLayoutp7/p8/p9 条目出发,会去寻找一个并不存在的构造器。
  • SparseCore 指针是 64 位 LLVM ptr(默认表示),携带 32 位 word-offset 值。 地址空间编号应从 {0, 201..225, 501, 502} 分配,绝不要从 {7, 8, 9} 分配。这两个范围必须保持不相交。
  • 精确复现 AS-id 表。 ID → 人类可读描述 → MemorySpace 枚举 → 池名称 → on/off-tile,包括六个保留空洞(206,207,209,210,221,222)、两个无池的 "Any" 别名超集(211 SflagAny, 225 SflagAnySynctile),以及两个存活但无描述的 ID(215 simem, 220 mar),这些都从 AddressSpaceDescription / AddressSpaceToMemorySpace / MemorySpaceToAddressSpace 恢复而来。
  • 将 tile 和 core 路由作为操作数携带,而不是作为指针位。 TEC 和 TAC tile-id cast 是 2 操作数 {base, tileId}(二者都声明 NOperands<2>);SCS/TC/plain cast 是 1 操作数 {base}OneOperand)。判别依据是 sequencer 的操作数元数,而不是指针。
TPU DataLayout单一实例 @ 0x973de15,由 Triple::computeDataLayout (0x1DAF4380) 发出
AS7/8/9 片段p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32 … ni:7:8:9(AMDGPU ABI,原样)
TPU/SC 代码中的 AS7/8/9 构造器 — 任何 SC/jellyfish 区段中都没有 …PointerType::get(7/8/9)
SC address-space 方案0x00 + 0xC9..0xE1 + 0x1F5/0x1F6(与 {7,8,9} 不相交)
AS-id 描述 switchLlvmTpuDialect::AddressSpaceDescription (0x135462C0) — 基数 201,跨度 24,另有 ID 0 / 501 / 502 分支
ID → MemorySpaceAddressSpaceToMemorySpace (0x14B78800);反向 MemorySpaceToAddressSpace (0x14B78780,表 0xAF36CE8,掩码 0x3FFF7F)
On-tile 分类器IsOffTileMemory (0x13D7AC00) = (ms & ~0x10) != 2 — 仅 MS 2 / 18 为 on-tile
SC pointer 寄存器内值MVT::i32 32 位 word offset(re-tag 保值;LowerADDRSPACECAST @ 0x13B70592
Tile/core 路由独立 SSA 操作数(tpu_tileid i32 / destination-id),绝不是指针位

AS7/8/9 胖指针保留区

目的

TPU TargetMachinellvm::Triple::computeDataLayout (0x1DAF4380) 的 TPU 分支构建它的 DataLayout,该分支生成位于 0x973DE15 的字符串单一实例。这个字符串大部分是常规内容,即 64 位默认指针、32 位 p2/p3/p5/p6、64 位 p1/p4,但它还携带了三个并非 TPU 原生的高位指针类别:

text
e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-
  p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-
  i64:64- … -n32:64-S32-A5-G1-ni:7:8:9
```text

`p7:160:256:256:32 / p8:128:128:128:48 / p9:192:256:256:32 / ni:7:8:9` 片段与 LLVM 的 **AMDGPU** target `DataLayout` 逐字节相同。在 AMDGPU 中,这三个空间属于 *buffer fat pointer* 家族:AS7 是 buffer fat pointer(128 位 `V#` resource descriptor 加 32 位 offset = 160 位),AS8 是裸 buffer resource("V#",128 位,48 位 index,即 "45-bit num_records" 诊断所指),AS9 是 buffer strided pointer(192 位)。`ni:7:8:9` 标记声明三者都是**非整数型**:它们不能通过 `ptrtoint`/`inttoptr` 与整数互转,原因正是它们的位是结构化 descriptor,而不是平坦地址。

这个片段之所以存在于 TPU layout 中,原因是来源:TPU 后端构建在同一个带有 AMDGPU 的 LLVM 中,buffer-fat-pointer lowering 机制也被编译进来。二进制携带 AMDGPU pass `AMDGPULowerBufferFatPointers` (`0x11999BA0`) 及其诊断信息的原文:`"global variables with a buffer fat pointer address space (7) are not supported"` 和 `"Use buffer resource pointers (address space 8) instead"` 都出现在该 pass 的函数体中。**这些内容都不能从 SparseCore codegen 到达。** 它们是死保留区,重新实现者可以忽略,但必须知道它们的存在,以免把它误认为 SC 指针模型。

### 三种格式

下面的逐字段布局是 AMDGPU ABI 对每个空间的定义;TPU 构建原样继承。`DataLayout` 四元组是以位为单位的 `size:abi-align:pref-align:index-width`。

| AS | `p` 条目 | 大小 | Index 宽度 | AMDGPU 角色 | 字段布局 (AMDGPU ABI) |
|---|---|---|---|---|---|
| 7 | `p7:160:256:256:32` | 160 bit | 32 bit | buffer **fat pointer** | 128-bit buffer resource (`V#`) + 32-bit offset |
| 8 | `p8:128:128:128:48` | 128 bit | 48 bit | buffer **resource** ("V#") | 128-bit descriptor; 48-bit index ⇒ "45-bit num_records" |
| 9 | `p9:192:256:256:32` | 192 bit | 32 bit | buffer **strided pointer** | 128-bit `V#` + 32-bit index + 32-bit stride |

> **GOTCHA —** 这三行描述的是 AS7/8/9 **如果**被构造出来,其位*会*表示什么。在 `libtpu` 0.0.40 中它们从未被构造。宽度和字段布局是逐字节相同的 AMDGPU ABI,二进制也带有匹配的 AMDGPU 诊断;TPU 构建把它们当作惰性保留区,任何位置都没有 TPU 构造器(见下一节)。不要把它们实现为 SparseCore 指针格式。

### 负面结论 — 没有 TPU 构造器

“没有 TPU op 构建 AS7/8/9 指针”这个断言是指令级负面结论。在这个代码库中物化 MLIR/LLVM 指针类型的方式,是调用 `LLVMPointerType::get(ctx, AS)` (`0x1746EB40`) 或 `PointerType::get(ctx, AS)` (`0x1DA72640`),并在调用前立即把地址空间字面量放入 `esi`/`edx`。扫描三个相关代码区段中的每一个此类调用点,即 SC MLIR-lowering 区段(`0x13500000..0x135D0000`)、SC IR-emitter 区段(`0x13800000..0x13E00000`)以及 jellyfish LLO-emitter 区段(`0x1D400000..0x1D800000`),地址空间参数**只会**出现在 `{0x00, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xD3}` 中。`7`、`8` 或 `9` 的出现次数为**零**。AMDGPU buffer-fat-pointer 诊断和 `ni:7:8:9` 标记解析到 `AMDGPULowerBufferFatPointers` 与通用 LLVM pass,而非任何 TPU 专用内容。

SparseCore 后端*确实*构建的唯一结构化指针聚合体是 `CircularBufferDescriptor`,这是一个 2 元素 LLVM struct `{CbReg, MemRefDescriptor}`,用 `mlir::StructBuilder` 组装;其中 `CbReg` 半边是一个作为 128 位 opaque CBREG 句柄复用的 `LLVMPPCFP128Type` 单例。它是由 SC CBREG 寄存器文件支撑的一等 struct 值,**不是**胖地址空间中的指针,也不触碰 AS7/8/9 保留区。(CBREG 窗口本身是下表中的 `0x1F5`/`0x1F6` 地址空间区段。)

> **NOTE — 保留区不是 TPU 结构化指针。** 很容易把 AS7/8/9 保留区解读成跨 core 寻址的 `{core/chip, space, offset}` 打包。字节证据否定了这一点:没有构造器,格式是死的 AMDGPU 样板,而 cross-core / cross-tile 路由走独立 SSA 操作数,即 remote cast 的 destination-id 操作数和 on-tile cast 的 `tpu_tileid` 操作数,绝不是指针位。

---

## SparseCore 地址空间 ID 表

### 目的

SparseCore 指针携带一个**数值地址空间 ID**,这个 ID,而不是任何指针位字段,命名该指针指向哪个物理内存池,以及它是在 tile 上可达,还是需要 DMA/stream/sync 才能到达。ID 空间通过三种相互一致的方式恢复:`AddressSpaceDescription` switch 将 ID 映射到人类可读字符串,`AddressSpaceToMemorySpace` 将 ID 映射到 `MemorySpace` 枚举,`MemorySpaceToAddressSpace` 是精确反函数。三者在 ID 上完全一致。`MemorySpace` 枚举是规范的 SparseCore 内存池枚举(22 个值,从 1 开始,值 8 是未使用空洞);其池名称来自 `stringifyMemorySpace`。

### 入口点

```text
LlvmTpuDialect::AddressSpaceDescription(int)        (0x135462C0)  ── ID → human string (the authority below)
  ├─ base 201, jump-table span 24 (IDs 201..225)
  └─ explicit arms for ID 0, 501, 502; reserved IDs fall through to "Unknown"

AddressSpaceToMemorySpace(uint)                     (0x14B78800)  ── ID → MemorySpace enum  (IDs 201..224)
MemorySpaceToAddressSpace(MemorySpace)              (0x14B78780)  ── MemorySpace → ID  (reverse table 0xAF36CE8, mask 0x3FFF7F)
stringifyMemorySpace(MemorySpace)                   (0x14B78240)  ── MemorySpace → pool name
IsOffTileMemory(MemorySpace)                        (0x13D7AC00)  ── (ms & ~0x10) != 2  → on-tile gate
GetAnyTypeFromAddressSpace(int)                     (0x1357B400)  ── concrete ID → "Any" may-alias superset

三个区段

20 个带描述的 ID 落在三个数值区段中,它们从 AddressSpaceDescription switch 逐字节恢复:

  • ID 0 — 继承的基底 Smem(标量内存,MemorySpace 1)。这是唯一与常规 LLVM default-AS 区域重叠的 SC ID;switch 的 default 分支只会对 0 返回 "Smem"
  • IDs 201..225 — SparseCore 专用区段(基数 0xC9)。25 个槽位中,17 个命名后备池,2 个(211, 225)命名无池的别名组,6 个(206, 207, 209, 210, 221, 222)是既无池也无描述的保留空洞。另有两个(215/220)携带存活的 MemorySpacesimem, mar)但没有描述字符串,所以 AddressSpaceDescription 会在它们上 fall through。
  • IDs 501, 502 — 两个 circular-buffer 空间(0x1F5/0x1F6),处于独立高位区段,支撑 CBREG 窗口。

AddressSpaceDescription 的函数体足够小,可以精确确认:对于 ID > 500,它返回 "TileSpmem Circular Buffer" (501) 或 "Smem Circular Buffer" (502);对于 201..225,它切换到下面的名称;无描述 ID(206,207,209,210,215,220,221,222return 当前结果 "Unknown";而 default 分支对 ID 0 返回 "Smem"

完整表

MS#MemorySpace 枚举值(从 1 开始;0 = 没有规范池,即别名组)。tile?IsOffTileMemory == false,只有 MS 2 和 MS 18 为 true。

IDhex描述MS#tile?备注
00x00Smem1smemoff基础 TPU 标量内存
2010xC9TileSpmem2tile_spmemON每 tile SC SRAM (KB)
2020xCASpmem3spmemoff芯片共享 SC SRAM (MB)
2030xCBHBM4hbmoff全局 (GB) embedding tables
2040xCCSflag5sflagoffsync-flag 内存(也包括 MS 22 sflag_tc
2050xCDVmem6vmemoffTC vector memory(handoff)
2060xCE(reserved)0空洞
2070xCF(reserved)0空洞
2080xD0Dreg7dregoffdata-register window
2090xD1(reserved)0空洞
2100xD2(reserved)0空洞
2110xD3SflagAny0(alias)offsflag may-alias superset
2120xD4SmemAny9smem_anyoffsmem may-alias superset
2130xD5HBMAny10hbm_anyoffhbm may-alias superset
2140xD6Timem11timemoff每 tile instruction memory
2150xD7(no desc → "Unknown")12simemoffSC instruction memory †
2160xD8IOVA13iovaoffI/O virtual address
2170xD9SflagTile14sflag_tileoff每 tile sflag bank
2180xDASpmemAny15spmem_anyoffspmem may-alias superset
2190xDBTileSmem16smem_tileoff每 tile SMEM
2200xDC(no desc → "Unknown")17maroffmemory-access-region †
2210xDD(reserved)0空洞
2220xDE(reserved)0空洞
2230xDFSflagScs20sflag_scsoff每 SCS sflag bank
2240xE0SmemScs21smem_scsoff每 SCS SMEM
2250xE1SflagAnySynctile0(alias)offsflag-any-synctile(无池)
5010x1F5TileSpmem Circular Buffer18tile_spmem_cbONCBREG-windowed TILE_SPMEM
5020x1F6Smem Circular Buffer19smem_cboffCBREG-windowed SMEM

NOTE — † ID 215 (simem) 和 220 (mar) 携带有效 MemorySpace(12 和 17),但 AddressSpaceDescription 没有它们的分支,并返回 fall-through 的 "Unknown",这是此构建中的 description-switch 空洞。它们的池名称是来自 stringifyMemorySpace 的规范名称;ID 本身是存活的,并且可以干净地通过 AddressSpaceToMemorySpace 映射。MemorySpace 22 (sflag_tc) 与 MS 5 一起复用 ID 204,所以反向表 dword_AF36CE8 中有一个 AS(0xCC)被两个 MemorySpace 值共享(条目 5 和 22)。

On-Tile 与 Off-Tile

IsOffTileMemory (0x13D7AC00) 是一行代码:return (a1 & 0xFFFFFFEF) != 2;,也就是 (ms & ~0x10) != 2。清除 bit 4 会把 MS 18(tile_spmem_cb,CBREG 别名)折叠到 MS 2(tile_spmem)上,所以只有两个 on-tile MemorySpace:tile_spmem 及其 circular-buffer 别名。其他一切,即 HBM、SPMEM、SMEM、SFLAG、VMEM、DREG、TIMEM、IOVA、MAR 和各 per-SCS bank,都是 off-tile,需要 DMA、stream 或 sync 才能到达。这个单一 bit-test 是 DMA 和 stream lowering 查询的访问语义门槛,也正是 TEC 需要 tile-id cast 的原因:它要把 on-tile TileSpmem (201) 指针转换成 execute-lane 寻址可用的 off-tile-addressable Spmem (202) 指针。

"Any" May-Alias 超集

五个 ID,即 211 SflagAny212 SmemAny213 HBMAny218 SpmemAny 和合成的 225 SflagAnySynctile,是 alias-analysis 通配符:当指针的确切 tile 或 core 静态未知时,SparseCore LLVM 后端会给它分配 may-alias 超集。三者(212/213/218)携带专用 *_any 池(MemorySpace 9/10/15,池 smem_any/hbm_any/spmem_any);另外两个(211 SflagAny225 SflagAnySynctile)完全携带 MemorySpaceAddressSpaceToMemorySpace 对它们返回 0,因此它们是没有物理池的纯别名分组。GetAnyTypeFromAddressSpace (0x1357B400) 会把具体 ID 规范化为其通配符:

text
201 TileSpmem  → 218 SpmemAny        205 Vmem      → 205 Vmem (self; no wildcard)
202 Spmem      → 218 SpmemAny        219 TileSmem  → 212 SmemAny
203 HBM        → 213 HBMAny            0 Smem       → 212 SmemAny
204 Sflag      → 211 SflagAny
```text

在已经是通配符的空间上,或在没有超集的叶子空间(Dreg, Timem, IOVA, SflagTile)上调用 `GetAnyTypeFromAddressSpace` 会 `LOG(FATAL)`;这些是叶子空间或已经规范化的空间。

---

## 实际的 SparseCore 指针表示

### 宽度与寄存器内值

SC 地址空间 ID(`0xC9`/`0xCA`/`0xCB`/`0xCC`/…)都没有出现在 `DataLayout` 的 `p` 列表中,所以每个都继承**默认 `p:64:64`**,即 64 位指针表示。但 SparseCore 指针携带的*值*是 32 位 SparseCore **word offset**:在 SelectionDAG 中,`TPUTargetLowering::LowerADDRSPACECAST` (`0x13B70480`) 会发出一个保值的自定义 `SDNode`(opcode `0xF3`,设置于 `0x13B70592`),其 `EVT = MVT::i32`(`0x13B70597` 处 `ecx = 0x7`,其中 `0x7` 是 `MVT::i32` 枚举值)。辅助诊断也一致:`"No GEP instruction on HBM address space allowed. On TPU, HBM pointers are at least full 32-bit."` (`0x9FF4DD5`),而 `SpmemAlignment` (`0x13DC5500`) 通过把每 SC 字节数除以 4 来计算 *word* 对齐。因此 SparseCore 指针至多是一个 64 位 LLVM ptr,其有意义内容是 32 位 word offset,绝不是 160/128/192 位 struct。

> **QUIRK —** re-tag 是保值的。两个 SC 空间之间的 `addrspacecast` 不改变 offset 值;它只改变附着在 64 位指针上的地址空间整数(并且在 tile-indexed TEC/TAC 情况下附加一个 tile-id 操作数)。`LowerADDRSPACECAST` 生成 `SDNode 0xF3 / MVT::i32`,携带相同的 word offset 输入和相同的 word offset 输出。重新实现者不能把 cast 建模为地址的算术变换;它是纯 tag 变更,加一个带外路由操作数。

### 每 AS 字段布局 — 路由是操作数,不是位

因为指针是没有结构化字段的平坦 32 位 word offset,胖指针通常会打包进位中的路由信息,改由建立该路由的 cast 上的**独立 SSA 操作数**携带。路由有两个维度,且每个都有自己的操作数:

```text
        SparseCore pointer  =  ⟨ 64-bit LLVM ptr (default repr) ; AS-id ∈ {0, 0xC9..0xE1, 0x1F5/0x1F6} ⟩
                                 value = 32-bit word offset (MVT::i32)

   routing is NOT in the pointer bits — it rides as paired operands on the cast:

     ┌─ tile-indexed (TEC / TAC, per-tile execute lanes) ─────────────────────────┐
     │  cast = tpu_addrspacecast_{spmem,smem,tec,…tec,tac}  →  2 operands         │
     │    operand 0 = base ptr (TileSpmem 0xC9 …)                                 │
     │    operand 1 = tpu_tileid  (i32 from the STILEID hardware register read)   │
     └────────────────────────────────────────────────────────────────────────────┘
     ┌─ singular-per-core (SCS / TC / plain) ─────────────────────────────────────┐
     │  cast = tpu_addrspacecast{,_scs,_tc,…scs}  →  1 operand                    │
     │    operand 0 = base ptr   (no tile id — these lanes are singular per core) │
     └────────────────────────────────────────────────────────────────────────────┘
     ┌─ cross-chip (remote) ─────────────────────────────────────────────────────┐
     │  the destination-id / remoteCoreId operand on the remote DMA / get_remote  │
     │  descriptor carries the {device, core, id} routing (not a pointer field)   │
     └────────────────────────────────────────────────────────────────────────────┘

元数分裂就是实际存在的每 AS “字段布局”:它编码在 cast op 的操作数数量中,并由 …::create 构造器签名逐字节确认(mangled 名中的 S6_ = 第二个 Value 操作数;没有它 = 一个操作数)。tpu_addrspacecast_tec::create (0x146D69C0) 的签名是 (OpBuilder, Location, Type, Value, Value),并发出两次 addOperands 调用,即 operand 0 = base ptroperand 1 = tile id,最后添加结果 Typetpu_addrspacecast_scs::create (0x146D5F80) 和 plain tpu_addrspacecast::create (0x146D5EA0) 接受单个 Value 并发出一次 addOperands。tile-id 源是 tpu_tileid::create (0x149883A0),签名 (OpBuilder, Location, Type),有零个 Value 操作数,因为它读取 SparseCore 标量 TID 寄存器(STILEID.VRES / stileid.u32),而不是消费一个值。

Cast 家族构造器操作数Tile id?Sequencer
tpu_addrspacecast (plain)0x146D5EA01 {base}nogeneric
tpu_addrspacecast_scs0x146D5F801 {base}noSCS
tpu_addrspacecast_tc0x146D68E01 {base}noTC
tpu_addrspacecast_tac— (NOperands<2>)2 {base, tileId}YESTAC
tpu_addrspacecast_smem0x146D65002 {base, tileId}YESTEC
tpu_addrspacecast_spmem0x146D67E02 {base, tileId}YESTEC
tpu_addrspacecast_tec0x146D69C02 {base, tileId}YESTEC
tpu_tileid (the i32 source)0x149883A00 (register read)

QUIRK — 2 操作数与 1 操作数的分裂完全由 sequencer 决定,而不是由源/目标地址空间决定。两个 tile-indexed lane,即 TEC 和 TAC,都声明 NOperands<2> 并携带 tile id;singular-per-core lane(SCS、TC 和 plain cast)声明 OneOperand,并且不携带。这是因为 tile-indexed lane 寻址 per-tile TileSpmem,因此需要运行时 tile-select;singular sequencer lane 在没有 per-tile index 的情况下寻址其内存。完整 16-cast 名单、from→to AS 映射和 lowering 函数体见 addrspacecast ISelTile-ID Cast;本页只记录为什么路由是操作数而不是指针位。

地址空间整数流

SC op 在其 memref attribute 上携带的 MemorySpace 枚举,会由 MemorySpaceToAddressSpace (0x14B78780) 转换成 LLVM 地址空间整数:它用 bitmask 0x3FFF7F 验证 ms - 1 <= 0x15(用 "Unsupported memory space" LOG(FATAL) 拒绝 MS-8 空洞和越界值),然后返回 dword_AF36CE8[ms - 1],这是一个 22 条目的表,是 AddressSpaceToMemorySpace 的精确反函数。因此数据路径是:SC op MemorySpace attr → LLVM address-space ID(此表)→ 带该 AS 的 64 位 LLVM 指针 → 默认 p:64:64 表示 → ISA 上的 32 位 word-offset 值。没有任何阶段构造 160/128/192 位胖指针,也没有任何阶段让地址空间 ID 离开 {0, 201..225, 501, 502} 区段。


相关组件

名称关系
AddressSpaceDescription (0x135462C0)本页枚举的 AS-id → name 表的权威来源
MemorySpaceToAddressSpace (0x14B78780)MemorySpace → AS-id 正向映射(指针的地址空间整数)
IsOffTileMemory (0x13D7AC00)驱动 tile-id-cast 要求的 on-tile/off-tile 门槛
tpu_tileid::create (0x149883A0)作为 TEC cast 第 2 个操作数输入的 i32 tile-id 源
AMDGPULowerBufferFatPointers (0x11999BA0)拥有(未使用)AS7/8/9 保留区及其诊断的 AMDGPU pass

交叉引用

  • SparseCore 概览 — Part IX 的导航入口;engine 名称、逐代存在性,以及指针所处的数据路径。
  • SparseCore 硬件架构 — SPMEM ↔ TILE_SPMEM 的物理拆分,以及这些地址空间命名的四层内存模型。
  • addrspacecast ISel — IR MemorySpaceCastllvm.addrspacecast 转换,以及完整的 16-cast from→to AS 映射。
  • Tile-ID Cast — on-tile 2 操作数 {base, tileId} cast lowering,以及 tile id 如何作为标量寄存器操作数到达 lowered TileSpmem load/store。
  • Stream Gather/Scatter — 根据这些地址空间 ID 分派以选择 embedding gather/scatter intrinsic 的 stream lowering。
  • Binary: extracted/libtpu-0.0.40-cp314-cp314-manylinux_2_31_x86_64/libtpu/libtpu.so (build-id 89edbbe81c5b328a958fe628a9f2207d)
  • 索引条目: Part IX — SparseCore & BarnaCore / SparseCore pointers & DMA — 返回索引