在静态单一赋值形式中实现基于寄存器的IR的方法

时间:2011-12-28 15:09:38

标签: compiler-construction compilation llvm ssa

我正在编写一个基于寄存器的字节码的编译器到具有静态单一分配(SSA)形式的IR(具体地说,从Dalvik VM字节码到LLVM IR,但我希望可以针对一般情况采取问题主题)我想知道最好的,或者理论上最干净的方法。

例如,如果我们有基于寄存器的指令:

add vA, vB, vC    (vA := vB + vC)
...
sub vA, vD, vE    (vA := vD - vE)

然后我们再也不能使用vA的旧值,因为它已被覆盖并替换为vD - vE。

在SSA表格中,我们会有更像

的内容
vA1 := vB + vC
...
vA2 := vD - vE

因为每个变量只分配一次。

问题在于,在基于寄存器的语言映射中,我们不需要SSA表单跟踪的这些先前值,因为我们只使用每个寄存器的最新值。对我来说,继续创建我们永远不会使用的新变量似乎是不好的做法,或者只是“肮脏”,但我想这就是你用表示得到的。

因此,我的问题是实现这种映射的最佳方式是什么(有点主观,抱歉)。我最初的想法是,因为我知道每个方法使用的(固定)寄存器数量,我可以跟踪每个寄存器的最新值,并且只使用它,但我不知道如何在实践中工作。

我期待听到您的想法。

1 个答案:

答案 0 :(得分:3)

嗯,一般来说,你必须使用类似于SSA构造算法的东西。在存在分支的情况下,事情可能会很复杂(例如,考虑到你有if-else之类的结构,并且只有一个寄存器只在“if”子句中被修改,但之后使用)。

说到LLVM IR - 只需简单地以非SSA格式发出内容(通过alloca在堆栈上分配寄存器并加载/存储值)然后只需让mem2reg为你清理一切。这就是clang,llvm-gcc和许多其他前端发出的东西:)