Skip to content

SSA 的 φ 节点

Phi node · Phi function · φ 节点

在 SSA 控制流汇合块中按实际进入的前驱边选择对应版本,并以并行方式定义合流值的伪指令。

条目类型
定义

形式陈述

设基本块 B控制流图中有按边标识的前驱 P1,,Pk静态单赋值形式中的 φ 节点

x:=ϕ(P1:x1,,Pk:xk)

位于 B 的入口,并定义一个新 SSA 名字 x。若执行由边 PiB 进入,x 的值就是离开 Pixi 的值。参数与前驱边一一对应;交换 CFG 边而不同时重排参数会改变语义。

φ 不是运行时把所有参数求值后任意挑选的普通函数。未走路径上的参数无需在本次执行中有值。一个块顶部的多个 φ 概念上并行读取各自前驱端的旧环境,再同时写入结果;顺序执行会制造错误的数据依赖。块参数表示把同一语义写为跳转实参与块形参,也必须保持边到实参位置的对应。

良构性还要求每条进入边恰有一个参数槽,参数类型与结果类型一致,且参数定义在对应边的尾端可用。若同一前驱块有两条不同标签的边进入 B,槽位应按边而非仅按前驱块编号;否则删除其中一条边或改变 switch 标签时会把仍存在的路径绑定到错误值。不可达前驱是否保留参数,则必须与 CFG 的不可达块策略一致。

直觉

变量版本化像给每次赋值发一张不同颜色的票。控制流汇合时,后续代码需要一张统一票,却不能预先知道执行来自哪条路。φ 节点站在汇合入口查看“刚才走的是哪条边”,把那条边携带的版本改名为新的统一版本。选择由控制历史决定,而不是由数值大小、真假或某个运行时随机函数决定。

将 φ 放在块入口还有一项结构意义:选中的定义必须沿对应前驱路径可得,而 φ 的结果从块入口起支配后续使用。它把原本隐含在路径中的 reaching-definition 选择显式化,因而既是语义合流点,也是 SSA 图中的定义节点。

例子与边界

菱形 CFG 有 ET,EF,TJ,FJ。在 T 中定义 x1:=7,在 F 中定义 x2:=9,则 J

x3:=ϕ(T:x1,F:x2).

沿 E,T,J 手算得到 x3=7;沿 E,F,Jx3=9。表达式 ϕ(x1,x2) 若遗漏边标签,只在前驱顺序永远稳定时才可安全简写。CFG 优化删除或复制前驱边后,必须同步维护参数,否则文本仍良构却选择错误版本。

循环头 H 的 φ 更能排除普通函数误解。入口 E 定义 i0:=0,循环体 L 定义 i2:=i1+1H 定义

i1:=ϕ(E:i0,L:i2).

第一次从 E 进入时取 0;回边进入时取上一轮计算出的 i2。第一次执行时 i2 尚不存在,这并不构成未定义读取,因为未选择的回边参数根本不被求值。

并行边界可由交换例看清。在块 Ja:=ϕ(P:a,Q:b)b:=ϕ(P:b,Q:a)。从 Q 进入时结果应同时为 (a,b)=(b,a)。若先把 a 写回旧名字 a,再计算第二条,便可能读到更新值而得到两个相同数。正确消解必须保留并行复制语义。

推论与应用

φ 的放置位置由定义路径何处汇合决定,经典算法使用迭代支配边界;但“可能汇合”不等于“变量此后有用”。minimal SSA、semi-pruned SSA 与 pruned SSA 对死 φ 的处理不同,活跃性条件必须另行说明。把每个多前驱块都为每个变量放 φ 虽可能保持语义,却会产生大量无用定义。

数据流分析通常把 φ 参数视为位于对应前驱边上的使用,而把 φ 结果视为块入口的定义。于是活跃性从某个 φ 参数只沿那条前驱传播,不应把同一 φ 的全部参数都标成每个前驱的使用。这个边敏感约定既影响 pruned 放置,也影响后续干涉图;把 φ 当块内普通指令会制造本来不存在的同时活跃。

φ 也不应被直接交给没有这种指令的机器。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, §§3–5.
  • Keith D. Cooper and Linda Torczon, Engineering a Compiler, 3rd ed., Morgan Kaufmann, 2023, Chapter 9.
  • Fabrice Rastello, ed., SSA-based Compiler Design, Springer, 2022, Chapters 2 and 9.
关系图谱5 个相邻概念 · 2 类关系

拖动节点调整位置。

显示关系

显示:依赖

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

使用的工具