如何在LLVM IR中为寄存器命名的本地值生成代码?

时间:2011-07-02 23:40:45

标签: code-generation llvm

我从源语言生成LLVM IR(.ll文件)。这种语言没有任何可变的局部变量,我还没有使用任何alloca,到目前为止,所有内容都在LLVM寄存器中。但它确实具有不可变的本地值。目前,它们工作正常,除非初始化部分是常量或另一个标识符。例如:

def fun(a: Int, b: Int) = {
  val n = a + b
  n + 2
}

这个编译很好,因为a + b编译到指令add i32 %a, %b,并且指令可以选择性地分配给本地值,因此该行变为:%n = add i32 %a, %b

另一方面,我无法为以下代码生成代码:

def fun() = {
  val n = 1
  n
}

我可以生成%n = bitcast i32 1 to i32但是bitcast并不适用于所有类型,并不是真的适用于此。嗯,我想在LLVM中确实没有特别的意图,否则我不会有这个问题。

但是,根据值的类型,是否有一个很好的解决方案而不产生大量不同的无操作指令? bitcast不适用于元组,例如:

error: invalid cast opcode for cast from '{ i32, i32 }' to '{ i32, i32 }'
%n = bitcast {i32, i32} {i32 1, i32 2} to {i32, i32}

然后,也许是因为IR中没有“复制”指令,我不应该尝试这样做,并且应该将%n替换为使用它的所有值?

1 个答案:

答案 0 :(得分:0)

您有两种可能性:

  1. 使用alloca,load和stores生成代码(检查例如clang或llvm-gcc在-O0的输出)然后使用-mem2reg优化传递将所有这些内容提升到LLVM寄存器
  2. 在任何地方使用1而不是%n。