在封闭范围内更新变量的SSA表示

时间:2017-07-17 15:08:50

标签: compiler-construction ssa

当编译器使用SSA表单表示代码时,对局部变量的更新将成为新变量。但是,当变量位于封闭范围内时,这并不总是有效,例如: (使用JavaScript语法进行说明,可能会出现多种语言的情况):

function f() {
    var x = 1;
    function g() {
        x++;
    }
    ...
}

通常的表达方式是什么?

1 个答案:

答案 0 :(得分:2)

闭包中使用的可变自由变量(在您的示例中为x)需要隐式地加上#34;盒装"。

有两个问题需要考虑。首先,生命周期:变量可能比创建它的范围更长。 (f可以返回g,或将其存储在持久容器中。)其次,共享:变量可以由fg或任何其他创建的函数修改f

最简单的解决方案是将变量更改为"框" (一个对象的容器,它是变量的值)。框本身是不可变的(也就是说,名称总是指同一个框)。变量值的修改和引用变为容器setter和getter方法。当然,必须在不再需要时动态分配和回收值的存储(与任何容器一样)。

在某些情况下可以进行优化 - 甚至可能是大多数情况。

首先,如果永远不修改变量,则可以为每个闭包提供值的副本,而不是装入值。

其次,如果变量是非共享的 - 它不会被执行f创建的任何其他函数关闭,f创建后g不会引用它。 - 变量可以简单地移到g的闭包中。

实际上,在上述两种情况下,闭包本身都成了盒子,但这样做的好处是不需要单独的动态分配。

证明这些优化在特定程序中的有效性需要良好的静态分析。第一个是直截了当的,因为修改很容易在语法上检测,但第二个需要流程分析(至少)。

在上文中,我使用了保守的描述,可以应用优化,只需要简单的流量分析;检测其他可能的应用程序更复杂。