MIPS 编译器中的寄存器使用哪个?

发布于 2024-12-19 04:34:16 字数 549 浏览 4 评论 0原文

我目前正在写一个玩具编译器作为作业,针对MIPS架构。

从高级语言转换时通常有 18 个可用寄存器:s0s7(由被调用者保存),以及 t0 到 < code>t9 是调用者保存的。

有了这 18 个可用寄存器,一个问题就出现了:在执行函数转换时我应该选择哪个寄存器。

每组都有其优点和缺点:

  1. 被调用者保存的寄存器必须分别在函数开始和结束时保存到堆栈中并从堆栈中恢复。
  2. 调用者保存的寄存器必须分别在调用子例程之前和之后保存到堆栈并从堆栈中恢复。

我很清楚,如果我采用静态策略来使用这些寄存器——无论策略是什么,比如更喜欢被调用者保存的寄存器而不是调用者保存的寄存器——我将不会获得最佳性能,因为很可能会出现不必要的寄存器加载/商店。

那么,使用这两组寄存器有什么好的做法吗?

I'm currently writing a toy compiler as a homework, targeted at the MIPS architecture.

There are 18 registers that are generally available when translating from higher-level languages: s0 to s7 which are callee-saved, and t0 to t9 which are caller-saved.

With these 18 registers available, a question emerges: which register should I prefer when performing the translation of a function.

Each set has its pros and cons:

  1. Callee-saved registers must be saved to and restored from the stack at the beginning and the end of a function, respectively.
  2. Caller-saved registers must be saved to and restored from the stack before and after invoking a subroutine, respectively.

It's clear to me that if I adopt a static strategy on using these registers — whatever the strategy is, like preferring callee-saved registers over caller-saved ones — I will not get the optimal performance since most probably there will be unnecessary register load/stores.

So, is there any good practices of using these two sets of registers?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

弥繁 2024-12-26 04:34:16

在非叶函数中更喜欢被调用者保存的寄存器,在叶函数中更喜欢调用者保存的寄存器。

在调用树的叶子和上一层,如果运气好的话,您将不会有任何保存。

Prefer callee-saved registers in non-leaf functions, prefer caller-saved registers in leaf functions.

At the leaves and one level up the call tree, with only a little luck, you won't have any saves whatsoever.

烟柳画桥 2024-12-26 04:34:16

这是一个比 chill 更好的解决方案,它以更细的粒度分配寄存器:

首先,我们对每个变量执行活跃度分析,并且:

  • 对于活跃度间隔跨越函数调用的变量:我们更喜欢被调用者保存的寄存器而不是调用者保存的寄存器。
  • 对于其活动间隔不跨越函数调用的变量:优先选择调用者保存的变量而不是被调用者保存的变量。

Here's a better solution than chill's, which allocates registers in a finer granularity:

First we perform liveness analysis for each variable, and:

  • For a variable the liveness interval of which spans a function call: we prefer callee-saved registers over caller-saved ones.
  • For a variable the liveness interval of which doesn't span a function call: prefer caller-saved ones over callee-saved ones.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文