当只有一个可能的前身时,使用phi节点有什么好处?例如,当我运行opt -loop-<some specific pass> some-cool-file.ll -S
时,如果我还没有添加一个,那么输出通常会包含一个只有一个可能的前任的phi节点。
示例:
endcond.loopexit: ; preds = %loop <- note: one predecessor
%res.lcssa = phi i64 [ %res, %loop ] ; I'm assuming this is from the
br label %endcond ; loop-closed ssa form pass
endcond:
%var = phi i64 [ %res.lcssa, %endcond.loopexit ], <other-pred>
如果只有一个可能的前任不应该与
完全相同endcond.loopexit: ; preds = %loop
br label %endcond ; res assigned a value in %loop
endcond:
%var = phi i64 [ %res, %endcond.loopexit ], <other-pred> ; use %res directly
不要误解我,我是phi节点的忠实粉丝,但我很好奇除了在只有一个可能的情况下添加phi节点时提高可读性和警告还有其他任何好处前身。
答案 0 :(得分:5)
当然,你是对的,两者是等价的。但是,前一个循环是LCSSA(循环闭合SSA)形式。这个表单提供了一些非常有用的保证,简化了许多循环优化。
这不是LLVM特有的,GCC也是如此。他们对LCSSA表格的具体好处有一个很好的总结:https://gcc.gnu.org/onlinedocs/gccint/LCSSA.html
在典型的编译传递管道期间,在通过InstCombine传递进行循环优化之后,将删除LCSSA PHI节点。 (如果在所有循环优化之后运行opt -instcombine
,您将获得预期的输出。)