编译器如何在几个寄存器中存储数百个变量?

时间:2015-06-08 23:10:11

标签: compiler-construction vm-implementation

假设你有一个只有4个寄存器A,B,C和D的虚拟机。编译器如何只用有限的空间存储这么多变量?

有多种方法可以做到这一点,还是有一种坚实的方法可以实现这一目标?什么是这个花哨的科学术语,它也被认为是一个复杂的问题?

由于

3 个答案:

答案 0 :(得分:4)

我建议您阅读Programming Language PragmaticsDragon Books,特别是register allocation上的章节。

简而言之,处理这种情况的方法很多。通常,编译器会构建一个intermediate representation,它可以是abstract machine,具有无限数量的寄存器或SSA形式。当为特定目标硬件/ OS生成代码时,这些抽象寄存器将根据使用频率或抽象寄存器的使用寿命(即原始变量)等标准分配给实际寄存器或堆栈位置。

取决于所选择的中间表示,有不同的方法(例如参见herehere)。如果您正在努力寻找最佳解决方案(即在实际寄存器中尽可能长时间地保留变量而不将它们溢出到堆栈中),问题可能会很困难,但是有更简单的方法,例如&# 34;线性扫描寄存器分配"当时间很重要时,例如在just-in-time compilations

如果您想深入了解代码,请查看LLVM基础架构以及their register allocationthis演示文稿。

答案 1 :(得分:1)

不适合寄存器(大多数东西)的东西存储在存储器中,只有在需要对寄存器进行操作时才会移入寄存器。您可能想阅读register allocation上的维基百科文章,这正是您要问的事情的名称。

答案 2 :(得分:1)

这是注册分配的主题。基本上所做的是编译器计算每个变量,同时使用其他变量。然后,编译器将构建干扰图,其中程序中使用的每个变量都有一个节点,并且所有节点之间的边缘同时存在。然后,这成为图形着色问题,其中颜色对应于机器上可用的寄存器。

如您所知,图形着色是NP-Complete问题,因此编译器实现了一种简单但非常有效的启发式算法。基本上,他们发现图中具有少于k个边的最高度节点,其中k是机器上的寄存器数。然后,我们删除此节点及其所有边缘,并递归地为剩余的图形着色。如果不存在这样的节点,我们采用最高度节点,并且溢出它,这意味着我们将它存储在堆栈上,并重新尝试删除该节点的着色过程。