【问题标题】:Methods to implement a register-based IR in static single assignment form以静态单一分配形式实现基于寄存器的 IR 的方法
【发布时间】: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


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-29
    • 2015-08-02
    • 2014-07-10
    • 2011-06-21
    • 2011-12-02
    相关资源
    最近更新 更多