我正试图确定 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
是否有任何示例将定义为临时 内并在循环外使用?谢谢!
答案 0 :(得分:3)
LLVM确实没有临时功能,它使用SSA。这是静态单一分配的简称,这里的关键词是单一。一切都是一个值,必须始终为该值赋一次。
任何东西都可以使用在使用时必须已分配的任何值。 “支配”是指您收到的错误消息中的“确实是先于”。 LLVM看到输入字符串为“ b”,代码将从while.cond
直接跳到while.end
,经过while.body
。
当您在循环结束后使用循环内的值时,事情可能会有些混乱。您可能需要认真考虑并关闭Slack和Facebook选项卡。但是LLVM不在乎。
答案 1 :(得分:0)
while.end
基本块只有while.cond
块作为其前身。因此,您无法访问while.body
中定义的变量。就像您要访问一个在另一个分支中定义的变量一样:
if(...)
int x = ...;
else
print(x);
相反,在循环入口块中声明所需的任何变量,然后在while.body
和while.end
中使用它。