我正在编写一个基于寄存器的字节码的编译器到具有静态单一分配(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表单跟踪的这些先前值,因为我们只使用每个寄存器的最新值。对我来说,继续创建我们永远不会使用的新变量似乎是不好的做法,或者只是“肮脏”,但我想这就是你用表示得到的。
因此,我的问题是实现这种映射的最佳方式是什么(有点主观,抱歉)。我最初的想法是,因为我知道每个方法使用的(固定)寄存器数量,我可以跟踪每个寄存器的最新值,并且只使用它,但我不知道如何在实践中工作。
我期待听到您的想法。
答案 0 :(得分:3)
嗯,一般来说,你必须使用类似于SSA构造算法的东西。在存在分支的情况下,事情可能会很复杂(例如,考虑到你有if-else之类的结构,并且只有一个寄存器只在“if”子句中被修改,但之后使用)。
说到LLVM IR - 只需简单地以非SSA格式发出内容(通过alloca在堆栈上分配寄存器并加载/存储值)然后只需让mem2reg为你清理一切。这就是clang,llvm-gcc和许多其他前端发出的东西:)