LLVM IR phi节点只有一个可能的前置节点

LLVM IR phi节点只有一个可能的前置节点,llvm,llvm-ir,ssa,Llvm,Llvm Ir,Ssa,当只有一个可能的前置节点时,使用phi节点有什么好处?例如,当我运行opt-loop-some-cool-file.ll-S时,如果我还没有添加一个phi节点,那么输出通常会包含一个phi节点,其中只有一个可能的前置节点 示例: endcond.loopexit: ; preds = %loop <- note: one predecessor %res.lcssa = phi i64 [ %res, %loop ] ; I'm assumin

当只有一个可能的前置节点时,使用phi节点有什么好处?例如,当我运行
opt-loop-some-cool-file.ll-S
时,如果我还没有添加一个phi节点,那么输出通常会包含一个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绝对正确,这两者是等价的。然而,前一个循环是LCSSA(循环闭合SSA)形式。这种形式提供了一些非常有用的保证,简化了许多循环优化

这不是特定于LLVM的,GCC也会这样做。他们很好地总结了LCSSA表格的具体好处:


在典型的编译过程管道中,LCSSA PHI节点将在INST过程进行循环优化后移除。(如果在所有循环优化之后使用
-instcombine
运行opt,您将获得预期的输出。)

谢谢!另一个完美的答案!所以我的后续问题是,我在每个块的开头(减去条目)使用一个phi节点来显示错误消息和可读性。那是好的还是坏的风格?或者,只要我使用
-instcombine
,这是否重要?我想有两个原因可能会让您担心错误消息和可读性:如果您出于任何原因手写IR,或者在调试生成IR的前端时。不管怎样,IR的使用完全取决于您——毕竟,最终用户永远不必知道IR,LLVM也不在乎(因为InstCombine,后来又因为phi节点被完全消除了)。
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