问题 LLVM程序集:为寄存器分配整数常量


我在写 编译器 使用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
       ^

文档显示 这样的例子 虽然。

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

  %2 = add i32 0, 1 ; FIXME

8767
2018-06-16 15:25


起源

为什么要将常量值绑定到名称?只需使用常量,就像在 tail call void @printf(i8* %1, i31 1)。顺便问一下,你是否正在生成IR作为文本?做什么的? - SK-logic
因为这对代码生成器来说更简单。我正在使用文本IR,因为我无法从我正在使用的语言轻松访问C / C ++库。 - Mildred


答案:


请参阅LLVMdev讨论 “如何为寄存器分配常量?” 正如Duncan Sands指出的那样:

让我说,一般来说这样做毫无意义。由于SSA格式,如果%x设置为5,则以后无法将其设置为其他内容。因此,在你使用%x的任何地方你也可以直接使用5而不是。一个常见的情况是你有一个寄存器%x,并且由于执行优化你发现实际上%x总是具有值5.你可以使用RAUW(也就是replaceAllUsesWith方法)将%x替换为5处。

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

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

有人指出了 alloca 方法将在优化后最终使用寄存器。

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


14
2018-06-16 19:41



最后,我解决了我的代码生成器,以避免在这里创建一个寄存器。 - Mildred


%1是 无名。请改用%name_here。


0
2018-06-18 18:02



似乎不适合我 - Mildred