【问题标题】:llvm caller saved registers not reloaded after function callllvm 调用者保存的寄存器在函数调用后未重新加载
【发布时间】:2017-01-28 04:17:33
【问题描述】:

我正在为 llvm 生成带有自定义 RISCV 后端的代码。当我在没有优化 (-O0) 的情况下编译时,程序可以正常工作。当我使用优化(-O2)进行编译时,调用后不会重新加载任何临时寄存器(调用者保存)。优化后的代码看起来确实有很好的寄存器分配,但它会做一些事情,比如用类初始化器的地址加载一个临时寄存器,然后在不重新加载寄存器的情况下多次调用初始化器。

load t1 %(foo)
jal t1
...
jal t1
...
jal t1

.bc 文件看起来与此伪代码基本相同,正确地声明了跨越所有函数调用的生存范围(lifetime.start 和lifetime.end)。

我认为寄存器分配器的策略是首先使用调用者保存的寄存器,所以我不认为这是错误声明我的寄存器的问题。在较旧的寄存器分配器中,我看到 loadRegFromStackSlot() 或 assignVirt2StackSlot() 函数用于溢出在被破坏后需要重新加载的寄存器。但是在贪婪的寄存器分配器中,我看不到发生这种情况的明显地方,所以我不知道如何调试我的后端可能缺少的东西。

也许我需要向代码生成器添加另一个通道或不同的通道。也许我的注册声明有问题,但我不这么认为。任何见解将不胜感激。

【问题讨论】:

    标签: llvm riscv register-allocation


    【解决方案1】:

    如果您使用 GitHub 上的 riscv/riscv-llvm,您可能需要获取以下修复。没有它我也看到了类似的问题。

    https://github.com/riscv/riscv-llvm/commit/ce8ac4e3ed8956a37bf330ee4a431c6fdfabac37

    以下问题报告指出了类似的问题,其中一个答案指向了上述变化:

    https://github.com/riscv/riscv-llvm/issues/32

    【讨论】:

    • 谢谢迈克,你是对的。上周晚些时候,我自己想出了这些变化——很难!
    猜你喜欢
    • 1970-01-01
    • 2019-08-18
    • 2012-03-05
    • 1970-01-01
    • 2018-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-15
    相关资源
    最近更新 更多