【问题标题】:How do compilers store hundreds of variables in only a few registers?编译器如何在几个寄存器中存储数百个变量?
【发布时间】:2015-06-08 23:10:10
【问题描述】:

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

是否有多种方法可以做到这一点,或者是否有一种可靠的方法可以完成?什么是花哨的科学术语,它是否被认为是一个复杂的问题?

谢谢

【问题讨论】:

  • 嗯,他们不会,是吗,他们将它们存储在内存位置:静态、堆、堆栈。寄存器的使用类似于高速缓存,受寄存器分配策略的约束。

标签: compiler-construction vm-implementation


【解决方案1】:

我建议你阅读Programming Language PragmaticsDragon Books,尤其是register allocation 上的章节。

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

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

如果您想深入研究代码,不妨看看 LLVM 基础架构和 their register allocationthis 演示文稿。

【讨论】:

  • 完美,感谢您提供的资源和所有这些!我会检查出来:)
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2013-11-11
      • 1970-01-01
      • 1970-01-01
      • 2013-07-22
      • 2013-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-04
      相关资源
      最近更新 更多