编译器 SSA

 

阅读:

https://blog.csdn.net/qq_29674357/article/details/78731713


SSA 概念

In compiler design, static single assignment form (often abbreviated as SSA form or simply SSA) is a property of an intermediate representation (IR), which requires that each variable is assigned exactly once, and every variable is defined before it is used.

SSA 形式的 IR 主要特征是每个变量只赋值一次。相比而言,非 SSA 形式的 IR 里一个变量可以赋值多次。为了得到 SSA 形式的 IR,起初的 IR 中的变量会被分割成不同的版本(version),每个定义(definition:静态分析术语,可以理解为赋值)对应着一个版本。在教科书中,通常会在旧的变量名后加上下标构成新的变量名,这也就是各个版本的名字。显然,在 SSA 形式中,UD 链(Use-Define Chain)是十分明确的。也就是说,变量的每一个使用(use:静态分析术语,可以理解为变量的读取)点只有唯一一个定义可以到达。 

 

SSA意义

SSA 通过简化程序中变量的特性,可以同时达到两种目的:第一,可以简化很多编译优化方法的过程;第二,对很多编译优化方法来说,可以获得更好的优化结果。下面给出一个例子:

 y := 1
 y := 2
 x := y

显然,我们一眼就可以看出,上述代码第一行的赋值行为是多余的,第三行使用的 y 值来自于第二行中的赋值。对于采用非 SSA 形式 IR 的编译器来说,它需要做数据流分析(具体来说是到达-定义分析)来确定选取哪一行的 y 值。但是对于 SSA 形式来说,就不存在这个问题了。如下所示:

 y1 := 1
 y2 := 2
 x1 := y2

显然,我们不需要做数据流分析就可以知道第三行中使用的 y 来自于第二行的定义,这个例子很好地说明了 SSA 的优势。除此之外,还有许多其他的优化算法在采用 SSA 形式之后优化效果得到了极大提高。甚至,有部分优化算法只能在 SSA 上做。

 

另外,龙书《》中有提到变量别名对给编译优化造成了困难,应该也可以借助这种SSA思想进行解决吧:

 

如何生成 SSA ?

把程序转换为 SSA 形式,最简单的方法就是将每个被赋值的变量用一个新的变量(版本)来取代同时将每次使用的变量替换为这个变量到达该程序点的“版本”。以下面左边的流图为例,右边的流图则是按照这个方法生成的 SSA:


这里写图片描述      这里写图片描述

图一 原程序流图          图二 SSA 形式的程序


眼尖的人可以发现,右边的图其实也不是最后的 SSA 形式,它最下面的基本块里 y 的使用尚未确定。由于该基本块的多个前驱基本块里都对 y 进行了定义,这里我们并不知道程序最终会从哪个前驱基本块到达该基本块。那么,我们如何知道 y 该取哪个版本?这时候 Φ(Phi) 函数便出场了。

我们在最后一个基本块的起始处添加了一条新的语句(Φ),它给出了 y 的一个新的定义 y3,根据程序的运行路径选择对应的版本。最后得出的 SSA 如下图所示:


这里写图片描述

图三 最终的 SSA


要注意的是,Φ 函数并不是一条实际的指令,现在的 target 指令集大多都不支持这样的指令,因此需要编译器做特殊处理。编译器后端在碰到 Φ 函数时,会进行相关处理得到正确的汇编代码,这个过程叫做 resolution。知乎有一个帖子专门介绍了 Phi 的处理方式,可以戳这里:Phi Node 是如何实现它的功能的?

 

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

First Snowflakes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值