1

我正在为基于寄存器的字节码编写一个编译器到一个具有静态单一分配 (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 表单跟踪的这些先前值,因为我们只使用每个寄存器的最新值。对我来说,继续创建我们永远不会使用的新变量似乎是一种不好的做法,或者只是“肮脏的”,但我想这就是你从表示中得到的。

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

我期待听到你的想法。

4

1 回答 1

3

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

说到 LLVM IR - 只需简单地以非 SSA 形式发出内容(通过 alloca 分配堆栈上的寄存器并将值加载/存储到 then),然后让 mem2reg 传递为您清理所有内容。这就是 clang、llvm-gcc 和许多其他前端发出这些东西的方式 :)

于 2011-12-28T16:33:56.153 回答