Compilation 如何为堆栈计算机编写LLVM后端?

Compilation 如何为堆栈计算机编写LLVM后端?,compilation,compiler-construction,llvm,Compilation,Compiler Construction,Llvm,当我试图在TableGen文件中构建LLVM后端而不定义RegisterClass实例时,它会抛出以下错误: error:No 'RegisterClass' subclasses defined 如何为LLVM定义堆栈机器目标(即不使用寄存器的目标)?不要这样做。LLVM DAG是专门为寄存器机设计的,对于堆栈机编译有一点价值。您需要一个自定义后端 我用于解决类似问题的一种方法(LLVM IR->FPGA上的堆栈软核)如下所示: 1) 超出SSA(reg2mem) 2) 构建一个中间树表示(

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

error:No 'RegisterClass' subclasses defined

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

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

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

1) 超出SSA(reg2mem)

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

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

4) 直接转换树,无需任何指令选择(您可以在LLVM IR级别上使用内部函数和自定义instcombine过程进行转换)

编辑:使用基于DAG的后端很难做到这一点,它从来就不打算以这种方式使用


我能想到的最接近的事情是使用DAG后端生成一个中间寄存器机器代码,然后使用后处理过程在可能的情况下对指令重新排序,并注入堆栈分配的变量access。也就是说,将每个堆栈机器指令表示为带有1个或2个寄存器参数和1个寄存器结果的伪指令。

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


谢谢您的回答,但我的目标是发现是否可以不编写自定义后端。所以,若你们知道任何方法可以做到这一点,请写一个更新你们的答案。我还在学习LLVM,我不清楚为什么DAG对基于堆栈的机器不好。文档说SelectionDAG看起来像这样:
(fadd:f32(fmul:f32(fadd:f32 W,X),Y),Z)
-就像lisp;)因此,将其转换为基于堆栈的机器代码似乎并不困难。例如,X86是基于堆栈的,因为据我所知,如果参数数大于寄存器数,则参数会在堆栈上传递。所以,如果我的理解是正确的,我应该避免将参数传递给寄存器,而直接将参数传递给堆栈。现在我创建了一个我不使用的寄存器,后端不工作(因为它还不完整),但我看不出有什么大问题。还有另一个选项-寄存器可以映射到内存。它比较慢,但应该可以工作。@DAG中的Kolesnichenkod边是虚拟寄存器。堆垛机要求这些边缘有一定的顺序(可能需要一些复杂的溢出)。你的选择就是把所有东西都洒出来,这是非常低效的。您可以在这里了解我是如何实现LLVM IR到堆栈机器的转换的:-通过树重新排序和溢出。