1. LLVM IR 的 SSA 结构以基本块与指令为单位,phi 节点如何表达控制流汇聚处的值选择?
LLVM IR 采用静态单赋值(SSA)形式,基本块与指令是基本单位,请解释 phi 节点如何表达控制流汇聚处根据来路选择不同值的这种语义?
- SSA 形式下每个变量只能赋值一次,但控制流汇聚处同一变量可能来自不同分支
- phi 节点的语义是"根据前驱基本块选择对应值"
- 名字与 SSA 版本的对应关系
在 SSA 形式下,每个变量(虚拟寄存器)只能被赋值一次,但当控制流从多个前驱汇聚到某个基本块时,同一个"逻辑变量"可能由不同路径携带不同的值。LLVM 用 phi 节点(phi 指令)表达这种汇聚语义,其形式为 phi type [val1, predBB1], [val2, predBB2], ...,表示"如果当前基本块是从 predBB1 进入的,就取 val1;如果从 predBB2 进入,就取 val2"。phi 节点必须位于基本块的入口处,且其操作数列表中的每个前驱块必须恰好对应一个值。由于 phi 节点本身也是一条虚拟寄存器定义指令,它使得整条 IR 仍然满足"每个临时名只定义一次"的 SSA 约束。
phi 节点是 SSA 的抽象本质:它把"一条路径上的沿用到汇聚处的值选择"显式化为一条指令,从而让每个值都有唯一的定义点,后续的传播、常量折叠、死代码消除等 Pass 才能安全地只沿 def-use 链工作,而不必担心控制流造成的歧义。phi 节点在翻译回机器码时会被消除(通过复制/移动指令解决),因此它只是 SSA 中间表示层的抽象。