Skip to content

SSA 构造算法

SSA construction algorithm · Dominance-based SSA construction · SSA 重命名

先以迭代支配边界插入 φ,再沿支配树用每变量版本栈重命名定义、使用和前驱边参数。

条目类型
算法

形式陈述

经典 SSA 构造分成不可互换的两阶段。第一阶段运行φ 节点放置算法,为每个变量在所需汇合块插入未完全命名的 φ。第二阶段取得由支配树算法计算的树,从入口深度优先遍历,并为每个原变量 v 维护版本计数器与栈 Sv

进入块 B 时,先给块首 φ 的结果创建新版本并压栈;随后按指令顺序把每个使用 v 改为 top(Sv),再给指令定义创建新版本并压栈。处理完块内指令后,对每条边 BC,把 C 中每个关于 v 的 φ 在该边位置的参数填为 top(Sv)。然后递归访问支配树中 B 的孩子。返回时弹出本块创建的全部版本,恢复兄弟子树应看到的环境。

核心不变量是:遍历到任一使用时,栈顶就是沿当前支配树路径最近的定义,因此该定义支配使用。入口参数先作为人工入口定义压栈;若栈为空却遇到使用,应按语言规则报告未初始化、插入未定义值,或拒绝输入,不能默默造一个常量。

算法还应区分普通使用与 φ 的边使用。普通指令在所在块的执行点读取栈顶;C 中 φ 对边 BC 的参数,则在离开 B 的抽象程序点读取。因而某定义只需支配该前驱边的尾,不必支配整个汇合块。验证器若统一用“定义支配使用所在块”检查,会错误拒绝菱形两支的合法 φ 参数。

直觉

支配树遍历像带着一叠按词法路径生效的版本卡片下行。进入一个定义所在块就盖上一张新卡,离开该块覆盖的支配子树就揭掉它。兄弟子树彼此不可见,因此回溯弹栈是正确性的一部分,而不是内存优化。

φ 参数在前驱块处理结束时填写,因为“从哪条边来”决定应看到哪个栈顶。φ 的结果则在进入自身块时先定义,供块内普通指令和循环体使用。将这两件事颠倒,会在循环头读到回边版本或在菱形中把两条边写成同一参数。

例子与边界

ET,EF,TJ,FJ,入口定义 x0:=0。遍历 T 时把 x1:=x0+1 压栈,并在边 TJ 的槽位写入 x1;退出 T 后弹回 x0。遍历 F 时创建 x2:=x0+2,在 FJ 写入 x2。最后进入 J,先把 φ 结果命名为 x3,返回使用改为 x3。每条使用的定义都可在支配树祖先链上找到。

若忘记退出 T 时弹栈,随后访问兄弟块 F 会把其右端误改成 x1+2;但控制路径 EF 从未执行 T 的定义。这是一个仅靠“名字各定义一次”检查不一定发现、却违反定义支配使用的具体错误。

循环例可逐栈执行。入口创建 i0:=0 后栈为 [i0];进入头部先给 φ 结果编号 i1,栈变 [i0,i1],条件使用 i1。遍历循环体时创建 i2:=i1+1,在回边槽填 i2;退出体弹出 i2,退出头部再弹 i1。入口边槽早先填 i0。最终 φ 为 i1:=ϕ(E:i0,L:i2),两条参数各由相应前驱端可见的栈顶产生。

不可达块不在入口支配树中。可先删除它们,或为不可达区域另建根并规定 undef 语义;直接让 DFS 遗漏而仍保留旧名字,会产出混合格式。内存、异常边和调用效果也需由独立模型承载:标量重命名不会解决未知别名,漏掉异常后继则可能漏填 φ 参数。

推论与应用

完成后可线性检查两项性质:每个 SSA 名字恰有一个定义,且普通使用的定义支配使用;φ 参数则要求其定义支配对应前驱边的末端。后一个条件不能误用“定义支配 φ 所在块”,因为某一分支定义通常不支配汇合块。

构造算法通常近似线性于 CFG、支配树和产生的 φ 总量,但最坏输出规模本身可能较大。实际实现会采用 pruned 放置、按变量稀疏工作表或 sealed-block 等替代构造法。无论实现路径如何,若声称得到同一 SSA 语义,都必须恢复边选择、唯一定义与支配使用这三项接口。

参考资料
  • Ron Cytron, Jeanne Ferrante, Barry K. Rosen, Mark N. Wegman, and F. Kenneth Zadeck, “Efficiently Computing Static Single Assignment Form and the Control Dependence Graph,” ACM TOPLAS 13(4), 1991, §5, Figures 11–12.
  • Andrew W. Appel, Modern Compiler Implementation in ML, Cambridge University Press, 1998, Chapter 19.
  • Keith D. Cooper and Linda Torczon, Engineering a Compiler, 3rd ed., Morgan Kaufmann, 2023, §9.3.
关系图谱7 个相邻概念 · 2 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系