【问题标题】:LLVM assembly: assign integer constant to registerLLVM 程序集:将整数常量分配给寄存器
【发布时间】:2011-06-16 15:25:09
【问题描述】:

我正在编写a compiler,它使用 LLVM 作为后端,我的编译器生成以下 LLVM 汇编代码

@0 = private constant [25 x i8] c"Hello World to %dntegers\00"

declare void @printf (i8*, i32)

define void @main () {
  %1 = getelementptr [25 x i8]* @0, i32 0, i32 0
  %2 = 1
  tail call void @printf(i8* %1, i32 %2)
  ret void
}

但我收到以下错误:

c.ll:8:8: error: expected instruction opcode
  %2 = 1
       ^

文档显示examples like that

你知道如何让它工作吗?目前,我正在使用:

  %2 = add i32 0, 1 ; FIXME

【问题讨论】:

  • 为什么要将常量值绑定到名称?只需在原地使用常量,如tail call void @printf(i8* %1, i31 1)。顺便说一句,您是否将 IR 生成为文本?干什么用的?
  • 因为这对于代码生成器来说更简单。我正在使用文本 IR,因为我无法从我使用的语言轻松访问 C/C++ 库。

标签: assembly integer constants llvm


【解决方案1】:

请参阅 LLVMdev 讨论 "How to assign a constant to a register?" 正如 Duncan Sands 所指出的那样:

让我说,一般来说这样做是没有意义的。由于 SSA 形式,如果 %x 设置为 5,则以后不能将其设置为其他值。因此,在您使用 %x 的任何地方,您都可以直接使用 5 。一个常见的情况是您有一个寄存器 %x,并且由于执行优化,您发现实际上 %x 将始终具有值 5。您可以使用 RAUW(又名 replaceAllUsesWith 方法)在任何地方将 %x 替换为 5。

线程确实生成了几个直接使用常量的替代方案:

  • 使用alloca 获取指针,存储到它,然后根据需要加载值。
  • 创建一个指向常量的全局变量,然后根据需要加载该值。

有人指出alloca的方式在优化后最终会使用寄存器。

无论如何,按照@SK-logic 的建议直接使用常量似乎是最干净的解决方案。

【讨论】:

  • 最后,我使用我的代码生成器来避免在此处创建寄存器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-11
相关资源
最近更新 更多