【问题标题】:How to write an LLVM backend for stack machine?如何为堆栈机编写 LLVM 后端?
【发布时间】:2016-08-16 07:39:47
【问题描述】:

当我尝试构建 LLVM 后端而不在 TableGen 文件中定义 RegisterClass 实例时,它会引发以下错误:

error:No 'RegisterClass' subclasses defined

如何为 LLVM 定义堆栈机器目标(即不使用寄存器)?

【问题讨论】:

标签: compilation compiler-construction llvm


【解决方案1】:

只是不要这样做。 LLVM DAG是专门为寄存器机设计的,对于栈机编译价值不大。您需要一个自定义后端。

我用于解决类似问题的一种方法(LLVM IR -> FPGA 上的堆栈软核)如下:

1) 脱离 SSA (reg2mem)

2) 构建中间树表示(即,如果顺序允许,将所有一次性寄存器分配压缩到树中)。这是主要的优化瓶颈,留下的寄存器分配越少越好。

3) 剩余寄存器的“寄存器分配”现在都表示为堆栈分配的变量(希望您的堆栈机器 ISA 允许)。

4) 直接翻译树,无需任何指令选择(您可以在 LLVM IR 级别上执行此操作,而不是使用内在函数和自定义 instcombine 通道)。

编辑:使用基于 DAG 的后端来做到这一点并不容易,它从来没有打算以这种方式使用。

我能想到的最接近的事情是使用 DAG 后端生成中间寄存器机器代码,然后使用后处理传递在可能的情况下重新排序指令,否则注入堆栈分配的变量访问。即,将每个堆栈机器指令表示为具有 1 个或 2 个寄存器参数和 1 个寄存器结果的伪指令。

【讨论】:

  • 感谢您的回答,但我的目标是发现是否可以不编写自定义后端。因此,如果您知道 任何 方法 - 请更新您的答案。
  • 我还在学习 LLVM,我不清楚为什么 DAG 不适合基于堆栈的机器。文档说 SelectionDAG 看起来像这样:(fadd:f32 (fmul:f32 (fadd:f32 W, X), Y), Z) - 就像 lisp ;) 所以将其转换为基于堆栈的机器代码似乎并不难。
  • 例如X86 基于堆栈的,因为据我所知,如果参数数量大于寄存器数量,则参数将在堆栈上传递。所以,如果我的理解是正确的,我应该避免将参数传递给寄存器并直接传递给堆栈。现在我创建了一个我不使用的寄存器,并且后端无法正常工作(因为它还不完整),但我看不出有什么大问题。
  • 还有另一种选择——寄存器可以映射到内存。它速度较慢,但​​应该可以工作。
  • @KolesnichenkoDS DAG 中的边是虚拟寄存器。 Stack machine 需要在这些边缘有一定的顺序(并且可能需要一些复杂的溢出)。你的选择就是把所有东西都洒出来,这是非常低效的。您可以在此处查看我如何将 LLVM IR 实现为堆栈机器转换:github.com/combinatorylogic/soc/blob/master/backends/small1/… - 具有树重新排序和溢出。
【解决方案2】:

虽然我同意不要这样做,但您应该看看 WebAssembly 后端。

https://github.com/llvm/llvm-project/tree/main/llvm/lib/Target/WebAssembly

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    • 2010-11-23
    • 2012-04-05
    • 2019-04-20
    • 2013-12-27
    • 2023-04-01
    相关资源
    最近更新 更多