不同范围内变量的静态单一赋值

时间:2015-05-12 06:10:16

标签: compiler-construction scope

我是一名学习编译器的学生,现在我对SSA形式的问题感到困惑。

与许多语言一样,如C,存在许多范围。当前作用域中的变量可以在其他作用域中修改,例如,可以在调用函数后更改全局变量的值,这会使某些优化不正确。此外,可以使用指针修改当前范围中的变量。

我们应该如何处理这种情况?

1 个答案:

答案 0 :(得分:1)

对于您所描述的问题,简单,保守的解决方案涉及如果某个值可能以难以或无法推理的方式发生变化,则永远不会保留该值的副本。

那究竟是什么意思呢?考虑以下C片段:

void bar(void);
int unsafe;

void foo(void) {
    unsafe++; // 1
    bar();
    printf("%d\n", unsafe); // 2
}

假设使用不执行interprocedural optimization或分析的编译器编译此代码。显然,编译器无法知道对bar的调用是否会改变unsafe。因此,编译器不得在unsafe的调用中保留bar的实时副本。相反,该值应该从#1处读取并立即写回内存,并在#2点从内存中读取。

结论:如果你无法明确证明在程序执行的某些部分保持全局变量的副本是安全的,那么每次访问它时都必须从内存中读取和/或写入内存变量。

类似的问题出现在指向局部变量的指针上,正如你所建议的那样:

void qux(void) {
    int x;
    int *px = &x;
    x = 10;
    *px = 100;
    printf("%d\n", x);
}

一个天真的编译器,未能检测到xaliased,可能会错误地输出10而不是100.保守的解决方案在这里类似:如果你有一个地址变量的地址,< em>从不保留副本 - 始终将其溢出到stack frame并根据需要加载/存储其值。此外,无论如何你必须这样做,以便x甚至首先拥有地址!

请注意,这里没有SSA表格的具体内容。无论您的中间代表是否采用SSA形式,问题及其解决方案都是相似的。