LLVM IR临时使用

LLVM IR temporaries use

我试图找出 LLVM IR 临时文件 是否可以在定义它们的循环之外使用。为此,我编译了以下简单的 C 代码:

while (*s == 'a')
{
    c = *s++;
}
*s = c;

正如我所怀疑的那样,循环外的最终写入 (*s = c) 已完成 与另一个临时 (%tmp5) 比读取到循环内部 (%tmp4)

while.body:      ; preds = %while.cond
  %tmp3 = load i8*, i8** %s.addr, align 8
  %incdec.ptr = getelementptr inbounds i8, i8* %tmp3, i32 1
  store i8* %incdec.ptr, i8** %s.addr, align 8
  %tmp4 = load i8, i8* %tmp3, align 1
  store i8 %tmp4, i8* %c, align 1
  br label %while.cond

while.end:       ; preds = %while.cond
  %tmp5 = load i8, i8* %c, align 1
  %tmp6 = load i8*, i8** %s.addr, align 8
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ; store i8 %tmp4, i8* %tmp6, align 1 ;
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  store i8 %tmp5, i8* %tmp6, align 1

当我编辑 *.ll 文件并手动将 %tmp5 替换为 %tmp4 时, 然后llvm-as不开心:

$ llvm-as modified.ll
Instruction does not dominate all uses!
%tmp4 = load i8, i8* %tmp3, align 1
store i8 %tmp4, i8* %tmp6, align 1

是否有任何示例定义临时文件 循环内和循环外使用?谢谢!

LLVM 并没有真正的临时对象,它使用 SSA。这是静态单一赋值的简称,这里的关键词是单一。一切都是一个值,该值必须始终分配 一次

任何东西都可以使用任何在使用时必须分配的值。 "Dominates" 在您收到的错误消息中表示 "provably comes before",即。 LLVM看到输入字符串是"b",代码会直接从while.cond跳到while.end,过去while.body.

当您在循环结束后使用循环内的值时,事情会变得有点混乱。您可能需要认真考虑并关闭 Slack 和 Facebook 选项卡。但是 LLVM 并不介意。

while.end 基本块只有 while.cond 块作为其前身。因此,您无法访问 while.body 中定义的变量。这就像你想从另一个分支访问一个定义在一个分支中的变量:

if(...)
   int x = ...;
else
   print(x);

相反,在循环入口块中声明您需要的任何变量,然后在 while.bodywhile.end 中使用它。