【发布时间】:2009-04-30 14:30:10
【问题描述】:
在编译器设计中,为什么调用者不能将其已用寄存器列表(在调用者保存安排的情况下它将推送)传递给被调用者,以便被调用者而不是调用者或被调用者寄存器保存安排可以将其使用的寄存器列表与调用者使用的寄存器进行比较。然后只有真正需要推送的寄存器才会被推送。我错过了什么吗?
【问题讨论】:
标签: compiler-construction cpu-registers register-allocation
在编译器设计中,为什么调用者不能将其已用寄存器列表(在调用者保存安排的情况下它将推送)传递给被调用者,以便被调用者而不是调用者或被调用者寄存器保存安排可以将其使用的寄存器列表与调用者使用的寄存器进行比较。然后只有真正需要推送的寄存器才会被推送。我错过了什么吗?
【问题讨论】:
标签: compiler-construction cpu-registers register-allocation
这是一个有趣的想法。我认为有两点使它不那么吸引人:
这里稍微详细说明了它的工作原理: 您可能希望调用者将列表打包成一个机器字作为位向量。然后你需要被调用者按位 - 并使用它自己的列表,有一条指令保存由结果位向量命名的所有寄存器。
因为您将不得不在堆栈上为最坏的情况保留空间,所以您不会节省太多——在现代、超标量、乱序处理器上,写入同一缓存行几乎免费。
如果您真正想要的是在运行时最小化加载和存储的数量,您只需使用所有调用者保存寄存器,这也是事实。这种策略还使得引发异常和抢先切换线程变得非常便宜,并且许多编译器(如OCaml)出于这个原因使用它。被调用者保存寄存器是一种尝试减少溢出和重新加载指令的代码大小的技巧。它们在许多情况下都可以工作,而且它们节省空间,因为调用站点的数量远远多于过程定义(平均而言,一个过程包含多个调用)。
有关调用者保存和被调用者保存寄存器之间权衡的更多信息,请参阅nice paper by Jack Davidson and David Whalley。
【讨论】:
这是非常低效的...您将需要解析列表(对于每个函数!)这是完全没有必要的。
【讨论】: