我正在考虑编译器,并且对它们如何维护指令的树形结构有疑问。基本上instructions似乎是一棵树。
outer.for.body:
...
%val1 = load i32, i32* %arrayidx3, !llvm.access.group !4
...
br label %inner.for.body
inner.for.body:
...
%val0 = load i32, i32* %arrayidx1, !llvm.access.group !3
...
store i32 %val0, i32* %arrayidx2, !llvm.access.group !3
...
br i1 %exitcond, label %inner.for.end, label %inner.for.body, !llvm.loop !1
inner.for.end:
...
store i32 %val1, i32* %arrayidx4, !llvm.access.group !4
...
br i1 %exitcond, label %outer.for.end, label %outer.for.body, !llvm.loop !2
outer.for.end: ; preds = %for.body
我想知道当您遇到这种情况时,该树如何维护:
function hello() {
foo()
if (x == 0) {
a()
} else {
b()
}
bar()
}
我认为这有点像(伪代码):
call %foo
br %xcondition label %a, label %b
call %bar
但这将意味着不再存在真正的二叉树,因为有3个分支:
a()
b()
bar()
但是即使如此,上面的代码也没有任何意义,因为bar()
或a()
都不会被调用,b()
不会被调用,而会跳过 (我猜)回来了。那就是我的问题所在。程序集或LLVM IR如何处理这种情况(或伪代码)。