【发布时间】:2011-12-28 15:09:38
【问题描述】:
我正在编写一个编译器,用于将基于寄存器的字节码转换为具有静态单一分配 (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 1/2 年了。那么,你还在为这个问题而努力吗?你有进步吗?
-
现在您的查询:我认为,您不希望 SSA 形式的 IR 将其转换为 LLVM。您使用 LLVM 以 SSA 形式获取 IR,以便您可以在此表单上进行许多数据流分析。例如。您使用 LLVM 将 C 代码转换为 SSA IR,然后执行数据流分析以进行一些优化。因此,确实,出于映射的目的,您确实不需要 SSA 形式的 IR。 SSA 的主要优点是具有易于使用的定义链。但是,您也可以使用reaching def 来计算。
-
另外,如前文所述,您需要在分支的“相遇”处组合值。如果您提供更多详细信息,可能会,我们可以就此进行更多讨论。
标签: compiler-construction compilation llvm ssa