2

在编译器设计中,为什么调用者不能将其已用寄存器列表(在调用者保存安排的情况下它将推送)传递给被调用者,以便被调用者可以比较它的而不是调用者或被调用者寄存器保存安排使用的寄存器列表到调用者使用的寄存器。然后只有真正需要推送的寄存器才会被推送。我错过了什么吗?

4

2 回答 2

5

这是一个有趣的想法。我认为有两件事使它不那么吸引人:

  • 无论如何,被调用者必须为最坏的情况保留堆栈空间。
  • 为了提高效率,您需要专门的指令来一次性存储和加载寄存器集。摩托罗拉 68000(也可能是 PowerPC)上有这样的说明,但它们并不流行。

下面是它必须如何工作的一点详细说明:您希望调用者将列表打包成一个机器字作为位向量。然后,您将需要被调用者按位并使用其自己的列表,该指令具有保存由结果位向量命名的所有寄存器的指令。

因为您将不得不为最坏的情况在堆栈上保留空间,所以您不会节省太多——在现代、超标量、无序处理器上,写入同一高速缓存行几乎是免费的。

同样,如果您真正想要的是在运行时最小化加载和存储的数量,您只需使用所有调用者保存寄存器。这种策略还使得引发异常和抢先切换线程变得非常便宜,并且许多编译器(如OCaml)出于这个原因使用它。被调用者保存寄存器是一种尝试减少溢出和重新加载指令的代码大小的技巧。它们在许多情况下都可以工作,并且它们节省空间,因为调用站点的数量远远超过过程定义(平均而言,一个过程包含多个调用)。

有关调用者保存和被调用者保存寄存器之间权衡的更多信息,请参阅Jack Davidson 和 David Whalley 的一篇不错的论文

于 2009-05-01T02:41:03.393 回答
2

这是非常低效的......您将需要解析列表(对于每个函数!)这是完全没有必要的。

于 2009-04-30T14:32:55.467 回答